EncodingTest.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <?php
  2. /**
  3. * Copyright (c) 2016 Vincent Petry <pvince81@owncloud.com>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. namespace Test\Files\Storage\Wrapper;
  9. class EncodingTest extends \Test\Files\Storage\Storage {
  10. public const NFD_NAME = 'ümlaut';
  11. public const NFC_NAME = 'ümlaut';
  12. /**
  13. * @var \OC\Files\Storage\Temporary
  14. */
  15. private $sourceStorage;
  16. protected function setUp(): void {
  17. parent::setUp();
  18. $this->sourceStorage = new \OC\Files\Storage\Temporary([]);
  19. $this->instance = new \OC\Files\Storage\Wrapper\Encoding([
  20. 'storage' => $this->sourceStorage
  21. ]);
  22. }
  23. protected function tearDown(): void {
  24. $this->sourceStorage->cleanUp();
  25. parent::tearDown();
  26. }
  27. public function directoryProvider() {
  28. $a = parent::directoryProvider();
  29. $a[] = [self::NFC_NAME];
  30. return $a;
  31. }
  32. public function fileNameProvider() {
  33. $a = parent::fileNameProvider();
  34. $a[] = [self::NFD_NAME . '.txt'];
  35. return $a;
  36. }
  37. public function copyAndMoveProvider() {
  38. $a = parent::copyAndMoveProvider();
  39. $a[] = [self::NFD_NAME . '.txt', self::NFC_NAME . '-renamed.txt'];
  40. return $a;
  41. }
  42. public function accessNameProvider() {
  43. return [
  44. [self::NFD_NAME],
  45. [self::NFC_NAME],
  46. ];
  47. }
  48. /**
  49. * @dataProvider accessNameProvider
  50. */
  51. public function testFputEncoding($accessName) {
  52. $this->sourceStorage->file_put_contents(self::NFD_NAME, 'bar');
  53. $this->assertEquals('bar', $this->instance->file_get_contents($accessName));
  54. }
  55. /**
  56. * @dataProvider accessNameProvider
  57. */
  58. public function testFopenReadEncoding($accessName) {
  59. $this->sourceStorage->file_put_contents(self::NFD_NAME, 'bar');
  60. $fh = $this->instance->fopen($accessName, 'r');
  61. $data = fgets($fh);
  62. fclose($fh);
  63. $this->assertEquals('bar', $data);
  64. }
  65. /**
  66. * @dataProvider accessNameProvider
  67. */
  68. public function testFopenOverwriteEncoding($accessName) {
  69. $this->sourceStorage->file_put_contents(self::NFD_NAME, 'bar');
  70. $fh = $this->instance->fopen($accessName, 'w');
  71. $data = fputs($fh, 'test');
  72. fclose($fh);
  73. $data = $this->sourceStorage->file_get_contents(self::NFD_NAME);
  74. $this->assertEquals('test', $data);
  75. $this->assertFalse($this->sourceStorage->file_exists(self::NFC_NAME));
  76. }
  77. /**
  78. * @dataProvider accessNameProvider
  79. */
  80. public function testFileExistsEncoding($accessName) {
  81. $this->sourceStorage->file_put_contents(self::NFD_NAME, 'bar');
  82. $this->assertTrue($this->instance->file_exists($accessName));
  83. }
  84. /**
  85. * @dataProvider accessNameProvider
  86. */
  87. public function testUnlinkEncoding($accessName) {
  88. $this->sourceStorage->file_put_contents(self::NFD_NAME, 'bar');
  89. $this->assertTrue($this->instance->unlink($accessName));
  90. $this->assertFalse($this->sourceStorage->file_exists(self::NFC_NAME));
  91. $this->assertFalse($this->sourceStorage->file_exists(self::NFD_NAME));
  92. }
  93. public function testNfcHigherPriority() {
  94. $this->sourceStorage->file_put_contents(self::NFC_NAME, 'nfc');
  95. $this->sourceStorage->file_put_contents(self::NFD_NAME, 'nfd');
  96. $this->assertEquals('nfc', $this->instance->file_get_contents(self::NFC_NAME));
  97. }
  98. public function encodedDirectoriesProvider() {
  99. return [
  100. [self::NFD_NAME, self::NFC_NAME],
  101. [self::NFD_NAME . '/' . self::NFD_NAME, self::NFC_NAME . '/' . self::NFC_NAME],
  102. [self::NFD_NAME . '/' . self::NFC_NAME . '/' .self::NFD_NAME, self::NFC_NAME . '/' . self::NFC_NAME . '/' . self::NFC_NAME],
  103. ];
  104. }
  105. /**
  106. * @dataProvider encodedDirectoriesProvider
  107. */
  108. public function testOperationInsideDirectory($sourceDir, $accessDir) {
  109. $this->sourceStorage->mkdir($sourceDir);
  110. $this->instance->file_put_contents($accessDir . '/test.txt', 'bar');
  111. $this->assertTrue($this->instance->file_exists($accessDir . '/test.txt'));
  112. $this->assertEquals('bar', $this->instance->file_get_contents($accessDir . '/test.txt'));
  113. $this->sourceStorage->file_put_contents($sourceDir . '/' . self::NFD_NAME, 'foo');
  114. $this->assertTrue($this->instance->file_exists($accessDir . '/' . self::NFC_NAME));
  115. $this->assertEquals('foo', $this->instance->file_get_contents($accessDir . '/' . self::NFC_NAME));
  116. // try again to make it use cached path
  117. $this->assertEquals('bar', $this->instance->file_get_contents($accessDir . '/test.txt'));
  118. $this->assertTrue($this->instance->file_exists($accessDir . '/test.txt'));
  119. $this->assertEquals('foo', $this->instance->file_get_contents($accessDir . '/' . self::NFC_NAME));
  120. $this->assertTrue($this->instance->file_exists($accessDir . '/' . self::NFC_NAME));
  121. }
  122. public function testCacheExtraSlash() {
  123. $this->sourceStorage->file_put_contents(self::NFD_NAME, 'foo');
  124. $this->assertEquals(3, $this->instance->file_put_contents(self::NFC_NAME, 'bar'));
  125. $this->assertEquals('bar', $this->instance->file_get_contents(self::NFC_NAME));
  126. clearstatcache();
  127. $this->assertEquals(5, $this->instance->file_put_contents('/' . self::NFC_NAME, 'baric'));
  128. $this->assertEquals('baric', $this->instance->file_get_contents(self::NFC_NAME));
  129. clearstatcache();
  130. $this->assertEquals(8, $this->instance->file_put_contents('/' . self::NFC_NAME, 'barbaric'));
  131. $this->assertEquals('barbaric', $this->instance->file_get_contents('//' . self::NFC_NAME));
  132. }
  133. public function sourceAndTargetDirectoryProvider() {
  134. return [
  135. [self::NFC_NAME . '1', self::NFC_NAME . '2'],
  136. [self::NFD_NAME . '1', self::NFC_NAME . '2'],
  137. [self::NFC_NAME . '1', self::NFD_NAME . '2'],
  138. [self::NFD_NAME . '1', self::NFD_NAME . '2'],
  139. ];
  140. }
  141. /**
  142. * @dataProvider sourceAndTargetDirectoryProvider
  143. */
  144. public function testCopyAndMoveEncodedFolder($sourceDir, $targetDir) {
  145. $this->sourceStorage->mkdir($sourceDir);
  146. $this->sourceStorage->mkdir($targetDir);
  147. $this->sourceStorage->file_put_contents($sourceDir . '/test.txt', 'bar');
  148. $this->assertTrue($this->instance->copy(self::NFC_NAME . '1/test.txt', self::NFC_NAME . '2/test.txt'));
  149. $this->assertTrue($this->instance->file_exists(self::NFC_NAME . '1/test.txt'));
  150. $this->assertTrue($this->instance->file_exists(self::NFC_NAME . '2/test.txt'));
  151. $this->assertEquals('bar', $this->instance->file_get_contents(self::NFC_NAME . '2/test.txt'));
  152. $this->assertTrue($this->instance->rename(self::NFC_NAME . '1/test.txt', self::NFC_NAME . '2/test2.txt'));
  153. $this->assertFalse($this->instance->file_exists(self::NFC_NAME . '1/test.txt'));
  154. $this->assertTrue($this->instance->file_exists(self::NFC_NAME . '2/test2.txt'));
  155. $this->assertEquals('bar', $this->instance->file_get_contents(self::NFC_NAME . '2/test2.txt'));
  156. }
  157. /**
  158. * @dataProvider sourceAndTargetDirectoryProvider
  159. */
  160. public function testCopyAndMoveFromStorageEncodedFolder($sourceDir, $targetDir) {
  161. $this->sourceStorage->mkdir($sourceDir);
  162. $this->sourceStorage->mkdir($targetDir);
  163. $this->sourceStorage->file_put_contents($sourceDir . '/test.txt', 'bar');
  164. $this->assertTrue($this->instance->copyFromStorage($this->instance, self::NFC_NAME . '1/test.txt', self::NFC_NAME . '2/test.txt'));
  165. $this->assertTrue($this->instance->file_exists(self::NFC_NAME . '1/test.txt'));
  166. $this->assertTrue($this->instance->file_exists(self::NFC_NAME . '2/test.txt'));
  167. $this->assertEquals('bar', $this->instance->file_get_contents(self::NFC_NAME . '2/test.txt'));
  168. $this->assertTrue($this->instance->moveFromStorage($this->instance, self::NFC_NAME . '1/test.txt', self::NFC_NAME . '2/test2.txt'));
  169. $this->assertFalse($this->instance->file_exists(self::NFC_NAME . '1/test.txt'));
  170. $this->assertTrue($this->instance->file_exists(self::NFC_NAME . '2/test2.txt'));
  171. $this->assertEquals('bar', $this->instance->file_get_contents(self::NFC_NAME . '2/test2.txt'));
  172. }
  173. public function testNormalizedDirectoryEntriesOpenDir() {
  174. $this->sourceStorage->mkdir('/test');
  175. $this->sourceStorage->mkdir('/test/' . self::NFD_NAME);
  176. $this->assertTrue($this->instance->file_exists('/test/' . self::NFC_NAME));
  177. $this->assertTrue($this->instance->file_exists('/test/' . self::NFD_NAME));
  178. $dh = $this->instance->opendir('/test');
  179. $content = [];
  180. while (($file = readdir($dh)) !== false) {
  181. if ($file != '.' and $file != '..') {
  182. $content[] = $file;
  183. }
  184. }
  185. $this->assertCount(1, $content);
  186. $this->assertEquals(self::NFC_NAME, $content[0]);
  187. }
  188. public function testNormalizedDirectoryEntriesGetDirectoryContent() {
  189. $this->sourceStorage->mkdir('/test');
  190. $this->sourceStorage->mkdir('/test/' . self::NFD_NAME);
  191. $this->assertTrue($this->instance->file_exists('/test/' . self::NFC_NAME));
  192. $this->assertTrue($this->instance->file_exists('/test/' . self::NFD_NAME));
  193. $content = iterator_to_array($this->instance->getDirectoryContent('/test'));
  194. $this->assertCount(1, $content);
  195. $this->assertEquals(self::NFC_NAME, $content[0]['name']);
  196. }
  197. public function testNormalizedGetMetaData() {
  198. $this->sourceStorage->mkdir('/test');
  199. $this->sourceStorage->mkdir('/test/' . self::NFD_NAME);
  200. $entry = $this->instance->getMetaData('/test/' . self::NFC_NAME);
  201. $this->assertEquals(self::NFC_NAME, $entry['name']);
  202. $entry = $this->instance->getMetaData('/test/' . self::NFD_NAME);
  203. $this->assertEquals(self::NFC_NAME, $entry['name']);
  204. }
  205. }