You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CleanTagsTest.php 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <?php
  2. /**
  3. * Copyright (c) 2015 Joas Schilling <nickvergessen@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\Repair;
  9. use OCP\DB\QueryBuilder\IQueryBuilder;
  10. use OCP\IUserManager;
  11. use OCP\Migration\IOutput;
  12. /**
  13. * Tests for the cleaning the tags tables
  14. *
  15. * @group DB
  16. *
  17. * @see \OC\Repair\CleanTags
  18. */
  19. class CleanTagsTest extends \Test\TestCase {
  20. /** @var \OC\Repair\CleanTags */
  21. protected $repair;
  22. /** @var \OCP\IDBConnection */
  23. protected $connection;
  24. /** @var \OCP\IUserManager|\PHPUnit\Framework\MockObject\MockObject */
  25. protected $userManager;
  26. /** @var int */
  27. protected $createdFile;
  28. /** @var IOutput */
  29. private $outputMock;
  30. protected function setUp(): void {
  31. parent::setUp();
  32. $this->outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
  33. ->disableOriginalConstructor()
  34. ->getMock();
  35. $this->userManager = $this->getMockBuilder(IUserManager::class)
  36. ->disableOriginalConstructor()
  37. ->getMock();
  38. $this->connection = \OC::$server->getDatabaseConnection();
  39. $this->repair = new \OC\Repair\CleanTags($this->connection, $this->userManager);
  40. $this->cleanUpTables();
  41. }
  42. protected function tearDown(): void {
  43. $this->cleanUpTables();
  44. parent::tearDown();
  45. }
  46. protected function cleanUpTables() {
  47. $qb = $this->connection->getQueryBuilder();
  48. $qb->delete('vcategory')
  49. ->execute();
  50. $qb->delete('vcategory_to_object')
  51. ->execute();
  52. $qb->delete('filecache')
  53. ->execute();
  54. }
  55. public function testRun() {
  56. $cat1 = $this->addTagCategory('TestRepairCleanTags', 'files'); // Retained
  57. $cat2 = $this->addTagCategory('TestRepairCleanTags2', 'files'); // Deleted: Category will be empty
  58. $this->addTagCategory('TestRepairCleanTags3', 'files'); // Deleted: Category is empty
  59. $cat3 = $this->addTagCategory('TestRepairCleanTags', 'contacts'); // Retained
  60. $this->addTagEntry($this->getFileID(), $cat2, 'files'); // Retained
  61. $this->addTagEntry($this->getFileID() + 1, $cat1, 'files'); // Deleted: File is NULL
  62. $this->addTagEntry(9999999, $cat3, 'contacts'); // Retained
  63. $this->addTagEntry($this->getFileID(), $cat3 + 1, 'files'); // Deleted: Category is NULL
  64. $this->assertEntryCount('vcategory_to_object', 4, 'Assert tag entries count before repair step');
  65. $this->assertEntryCount('vcategory', 4, 'Assert tag categories count before repair step');
  66. self::invokePrivate($this->repair, 'deleteOrphanFileEntries', [$this->outputMock]);
  67. $this->assertEntryCount('vcategory_to_object', 3, 'Assert tag entries count after cleaning file entries');
  68. $this->assertEntryCount('vcategory', 4, 'Assert tag categories count after cleaning file entries');
  69. self::invokePrivate($this->repair, 'deleteOrphanTagEntries', [$this->outputMock]);
  70. $this->assertEntryCount('vcategory_to_object', 2, 'Assert tag entries count after cleaning tag entries');
  71. $this->assertEntryCount('vcategory', 4, 'Assert tag categories count after cleaning tag entries');
  72. self::invokePrivate($this->repair, 'deleteOrphanCategoryEntries', [$this->outputMock]);
  73. $this->assertEntryCount('vcategory_to_object', 2, 'Assert tag entries count after cleaning category entries');
  74. $this->assertEntryCount('vcategory', 2, 'Assert tag categories count after cleaning category entries');
  75. $this->addTagCategory('TestRepairCleanTags', 'contacts', 'userExists'); // Retained
  76. $this->assertEntryCount('vcategory', 3, 'Assert tag categories count before cleaning categories by users');
  77. $this->userManager->expects($this->exactly(2))
  78. ->method('userExists')
  79. ->willReturnMap([
  80. ['userExists', true],
  81. ['TestRepairCleanTags', false],
  82. ]);
  83. self::invokePrivate($this->repair, 'deleteOrphanTags', [$this->outputMock]);
  84. $this->assertEntryCount('vcategory', 1, 'Assert tag categories count after cleaning categories by users');
  85. }
  86. /**
  87. * @param string $tableName
  88. * @param int $expected
  89. * @param string $message
  90. */
  91. protected function assertEntryCount($tableName, $expected, $message = '') {
  92. $qb = $this->connection->getQueryBuilder();
  93. $result = $qb->select($qb->func()->count('*'))
  94. ->from($tableName)
  95. ->execute();
  96. $this->assertEquals($expected, $result->fetchColumn(), $message);
  97. }
  98. /**
  99. * Adds a new tag category to the database
  100. *
  101. * @param string $category
  102. * @param string $type
  103. * @param string $user
  104. * @return int
  105. */
  106. protected function addTagCategory($category, $type, $user = 'TestRepairCleanTags') {
  107. $qb = $this->connection->getQueryBuilder();
  108. $qb->insert('vcategory')
  109. ->values([
  110. 'uid' => $qb->createNamedParameter($user),
  111. 'category' => $qb->createNamedParameter($category),
  112. 'type' => $qb->createNamedParameter($type),
  113. ])
  114. ->execute();
  115. return (int) $this->getLastInsertID('vcategory', 'id');
  116. }
  117. /**
  118. * Adds a new tag entry to the database
  119. * @param int $objectId
  120. * @param int $category
  121. * @param string $type
  122. */
  123. protected function addTagEntry($objectId, $category, $type) {
  124. $qb = $this->connection->getQueryBuilder();
  125. $qb->insert('vcategory_to_object')
  126. ->values([
  127. 'objid' => $qb->createNamedParameter($objectId, IQueryBuilder::PARAM_INT),
  128. 'categoryid' => $qb->createNamedParameter($category, IQueryBuilder::PARAM_INT),
  129. 'type' => $qb->createNamedParameter($type),
  130. ])
  131. ->execute();
  132. }
  133. /**
  134. * Gets the last fileid from the file cache
  135. * @return int
  136. */
  137. protected function getFileID() {
  138. if ($this->createdFile) {
  139. return $this->createdFile;
  140. }
  141. $qb = $this->connection->getQueryBuilder();
  142. // We create a new file entry and delete it after the test again
  143. $fileName = $this->getUniqueID('TestRepairCleanTags', 12);
  144. $qb->insert('filecache')
  145. ->values([
  146. 'path' => $qb->createNamedParameter($fileName),
  147. 'path_hash' => $qb->createNamedParameter(md5($fileName)),
  148. ])
  149. ->execute();
  150. $fileName = $this->getUniqueID('TestRepairCleanTags', 12);
  151. $qb->insert('filecache')
  152. ->values([
  153. 'path' => $qb->createNamedParameter($fileName),
  154. 'path_hash' => $qb->createNamedParameter(md5($fileName)),
  155. ])
  156. ->execute();
  157. $this->createdFile = (int) $this->getLastInsertID('filecache', 'fileid');
  158. return $this->createdFile;
  159. }
  160. /**
  161. * @param $tableName
  162. * @param $idName
  163. * @return int
  164. */
  165. protected function getLastInsertID($tableName, $idName) {
  166. return $this->connection->lastInsertId("*PREFIX*$tableName");
  167. }
  168. }