summaryrefslogtreecommitdiffstats
path: root/tests/lib/Repair
diff options
context:
space:
mode:
Diffstat (limited to 'tests/lib/Repair')
-rw-r--r--tests/lib/Repair/CleanTagsTest.php181
-rw-r--r--tests/lib/Repair/DropOldJobsTest.php48
-rw-r--r--tests/lib/Repair/DropOldTablesTest.php46
-rw-r--r--tests/lib/Repair/OldGroupMembershipSharesTest.php136
-rw-r--r--tests/lib/Repair/RemoveGetETagEntriesTest.php90
-rw-r--r--tests/lib/Repair/RepairCollationTest.php88
-rw-r--r--tests/lib/Repair/RepairInnoDBTest.php78
-rw-r--r--tests/lib/Repair/RepairInvalidSharesTest.php201
-rw-r--r--tests/lib/Repair/RepairLegacyStoragesTest.php335
-rw-r--r--tests/lib/Repair/RepairMimeTypesTest.php582
-rw-r--r--tests/lib/Repair/RepairSharePropagationTest.php57
-rw-r--r--tests/lib/Repair/RepairSqliteAutoincrementTest.php89
-rw-r--r--tests/lib/Repair/UpdateOutdatedOcsIdsTest.php80
-rw-r--r--tests/lib/Repair/fixtures/dropoldtables.xml24
14 files changed, 2035 insertions, 0 deletions
diff --git a/tests/lib/Repair/CleanTagsTest.php b/tests/lib/Repair/CleanTagsTest.php
new file mode 100644
index 00000000000..804fa4f66c9
--- /dev/null
+++ b/tests/lib/Repair/CleanTagsTest.php
@@ -0,0 +1,181 @@
+<?php
+/**
+ * Copyright (c) 2015 Joas Schilling <nickvergessen@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Repair;
+use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\Migration\IOutput;
+
+/**
+ * Tests for the cleaning the tags tables
+ *
+ * @group DB
+ *
+ * @see \OC\Repair\CleanTags
+ */
+class CleanTagsTest extends \Test\TestCase {
+
+ /** @var \OC\Repair\CleanTags */
+ protected $repair;
+
+ /** @var \OCP\IDBConnection */
+ protected $connection;
+
+ /** @var int */
+ protected $createdFile;
+
+ /** @var IOutput */
+ private $outputMock;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->connection = \OC::$server->getDatabaseConnection();
+ $this->repair = new \OC\Repair\CleanTags($this->connection);
+ $this->cleanUpTables();
+ }
+
+ protected function tearDown() {
+ $this->cleanUpTables();
+
+ parent::tearDown();
+ }
+
+ protected function cleanUpTables() {
+ $qb = $this->connection->getQueryBuilder();
+ $qb->delete('vcategory')
+ ->execute();
+
+ $qb->delete('vcategory_to_object')
+ ->execute();
+
+ $qb->delete('filecache')
+ ->execute();
+ }
+
+ public function testRun() {
+ $cat1 = $this->addTagCategory('TestRepairCleanTags', 'files'); // Retained
+ $cat2 = $this->addTagCategory('TestRepairCleanTags2', 'files'); // Deleted: Category will be empty
+ $this->addTagCategory('TestRepairCleanTags3', 'files'); // Deleted: Category is empty
+ $cat3 = $this->addTagCategory('TestRepairCleanTags', 'contacts'); // Retained
+
+ $this->addTagEntry($this->getFileID(), $cat2, 'files'); // Retained
+ $this->addTagEntry($this->getFileID() + 1, $cat1, 'files'); // Deleted: File is NULL
+ $this->addTagEntry(9999999, $cat3, 'contacts'); // Retained
+ $this->addTagEntry($this->getFileID(), $cat3 + 1, 'files'); // Deleted: Category is NULL
+
+ $this->assertEntryCount('vcategory_to_object', 4, 'Assert tag entries count before repair step');
+ $this->assertEntryCount('vcategory', 4, 'Assert tag categories count before repair step');
+
+ self::invokePrivate($this->repair, 'deleteOrphanFileEntries', [$this->outputMock]);
+ $this->assertEntryCount('vcategory_to_object', 3, 'Assert tag entries count after cleaning file entries');
+ $this->assertEntryCount('vcategory', 4, 'Assert tag categories count after cleaning file entries');
+
+ self::invokePrivate($this->repair, 'deleteOrphanTagEntries', [$this->outputMock]);
+ $this->assertEntryCount('vcategory_to_object', 2, 'Assert tag entries count after cleaning tag entries');
+ $this->assertEntryCount('vcategory', 4, 'Assert tag categories count after cleaning tag entries');
+
+ self::invokePrivate($this->repair, 'deleteOrphanCategoryEntries', [$this->outputMock]);
+ $this->assertEntryCount('vcategory_to_object', 2, 'Assert tag entries count after cleaning category entries');
+ $this->assertEntryCount('vcategory', 2, 'Assert tag categories count after cleaning category entries');
+ }
+
+ /**
+ * @param string $tableName
+ * @param int $expected
+ * @param string $message
+ */
+ protected function assertEntryCount($tableName, $expected, $message = '') {
+ $qb = $this->connection->getQueryBuilder();
+ $result = $qb->select($qb->createFunction('COUNT(*)'))
+ ->from($tableName)
+ ->execute();
+
+ $this->assertEquals($expected, $result->fetchColumn(), $message);
+ }
+
+ /**
+ * Adds a new tag category to the database
+ *
+ * @param string $category
+ * @param string $type
+ * @return int
+ */
+ protected function addTagCategory($category, $type) {
+ $qb = $this->connection->getQueryBuilder();
+ $qb->insert('vcategory')
+ ->values([
+ 'uid' => $qb->createNamedParameter('TestRepairCleanTags'),
+ 'category' => $qb->createNamedParameter($category),
+ 'type' => $qb->createNamedParameter($type),
+ ])
+ ->execute();
+
+ return (int) $this->getLastInsertID('vcategory', 'id');
+ }
+
+ /**
+ * Adds a new tag entry to the database
+ * @param int $objectId
+ * @param int $category
+ * @param string $type
+ */
+ protected function addTagEntry($objectId, $category, $type) {
+ $qb = $this->connection->getQueryBuilder();
+ $qb->insert('vcategory_to_object')
+ ->values([
+ 'objid' => $qb->createNamedParameter($objectId, IQueryBuilder::PARAM_INT),
+ 'categoryid' => $qb->createNamedParameter($category, IQueryBuilder::PARAM_INT),
+ 'type' => $qb->createNamedParameter($type),
+ ])
+ ->execute();
+ }
+
+ /**
+ * Gets the last fileid from the file cache
+ * @return int
+ */
+ protected function getFileID() {
+ if ($this->createdFile) {
+ return $this->createdFile;
+ }
+
+ $qb = $this->connection->getQueryBuilder();
+
+ // We create a new file entry and delete it after the test again
+ $fileName = $this->getUniqueID('TestRepairCleanTags', 12);
+ $qb->insert('filecache')
+ ->values([
+ 'path' => $qb->createNamedParameter($fileName),
+ 'path_hash' => $qb->createNamedParameter(md5($fileName)),
+ ])
+ ->execute();
+ $fileName = $this->getUniqueID('TestRepairCleanTags', 12);
+ $qb->insert('filecache')
+ ->values([
+ 'path' => $qb->createNamedParameter($fileName),
+ 'path_hash' => $qb->createNamedParameter(md5($fileName)),
+ ])
+ ->execute();
+
+ $this->createdFile = (int) $this->getLastInsertID('filecache', 'fileid');
+ return $this->createdFile;
+ }
+
+ /**
+ * @param $tableName
+ * @param $idName
+ * @return int
+ */
+ protected function getLastInsertID($tableName, $idName) {
+ return $this->connection->lastInsertId("*PREFIX*$tableName");
+ }
+}
diff --git a/tests/lib/Repair/DropOldJobsTest.php b/tests/lib/Repair/DropOldJobsTest.php
new file mode 100644
index 00000000000..d83ecbe59c4
--- /dev/null
+++ b/tests/lib/Repair/DropOldJobsTest.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Copyright (c) 2015 Arthur Schiwon <blizzz@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Repair;
+
+use OCP\BackgroundJob\IJobList;
+use OCP\Migration\IOutput;
+
+/**
+ * Tests for the dropping old tables
+ *
+ * @group DB
+ *
+ * @see \OC\Repair\DropOldTables
+ */
+class DropOldJobsTest extends \Test\TestCase {
+ /** @var IJobList */
+ protected $jobList;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->jobList = \OC::$server->getJobList();
+ $this->jobList->add('OC\Cache\FileGlobalGC');
+ $this->jobList->add('OC_Cache_FileGlobalGC');
+ }
+
+ public function testRun() {
+ $this->assertTrue($this->jobList->has('OC\Cache\FileGlobalGC', null), 'Asserting that the job OC\Cache\FileGlobalGC exists before repairing');
+ $this->assertTrue($this->jobList->has('OC_Cache_FileGlobalGC', null), 'Asserting that the job OC_Cache_FileGlobalGC exists before repairing');
+
+ /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */
+ $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $repair = new \OC\Repair\DropOldJobs($this->jobList);
+ $repair->run($outputMock);
+
+ $this->assertFalse($this->jobList->has('OC\Cache\FileGlobalGC', null), 'Asserting that the job OC\Cache\FileGlobalGC does not exist after repairing');
+ $this->assertFalse($this->jobList->has('OC_Cache_FileGlobalGC', null), 'Asserting that the job OC_Cache_FileGlobalGC does not exist after repairing');
+ }
+}
diff --git a/tests/lib/Repair/DropOldTablesTest.php b/tests/lib/Repair/DropOldTablesTest.php
new file mode 100644
index 00000000000..1f5a4c15295
--- /dev/null
+++ b/tests/lib/Repair/DropOldTablesTest.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Copyright (c) 2015 Joas Schilling <nickvergessen@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Repair;
+use OCP\Migration\IOutput;
+
+/**
+ * Tests for the dropping old tables
+ *
+ * @group DB
+ *
+ * @see \OC\Repair\DropOldTables
+ */
+class DropOldTablesTest extends \Test\TestCase {
+ /** @var \OCP\IDBConnection */
+ protected $connection;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->connection = \OC::$server->getDatabaseConnection();
+ $manager = new \OC\DB\MDB2SchemaManager($this->connection);
+ $manager->createDbFromStructure(__DIR__ . '/fixtures/dropoldtables.xml');
+ }
+
+ public function testRun() {
+ $this->assertFalse($this->connection->tableExists('sharing'), 'Asserting that the table oc_sharing does not exist before repairing');
+ $this->assertTrue($this->connection->tableExists('permissions'), 'Asserting that the table oc_permissions does exist before repairing');
+
+ /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */
+ $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $repair = new \OC\Repair\DropOldTables($this->connection);
+ $repair->run($outputMock);
+
+ $this->assertFalse($this->connection->tableExists('sharing'), 'Asserting that the table oc_sharing does not exist after repairing');
+ $this->assertFalse($this->connection->tableExists('permissions'), 'Asserting that the table oc_permissions does not exist after repairing');
+ }
+}
diff --git a/tests/lib/Repair/OldGroupMembershipSharesTest.php b/tests/lib/Repair/OldGroupMembershipSharesTest.php
new file mode 100644
index 00000000000..cc04a80eef9
--- /dev/null
+++ b/tests/lib/Repair/OldGroupMembershipSharesTest.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * Copyright (c) 2015 Vincent Petry <pvince81@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Repair;
+
+use OC\Repair\OldGroupMembershipShares;
+use OC\Share\Constants;
+use OCP\Migration\IOutput;
+
+/**
+ * Class OldGroupMembershipSharesTest
+ *
+ * @group DB
+ *
+ * @package Test\Repair
+ */
+class OldGroupMembershipSharesTest extends \Test\TestCase {
+
+ /** @var OldGroupMembershipShares */
+ protected $repair;
+
+ /** @var \OCP\IDBConnection */
+ protected $connection;
+
+ /** @var \OCP\IGroupManager|\PHPUnit_Framework_MockObject_MockObject */
+ protected $groupManager;
+
+ protected function setUp() {
+ parent::setUp();
+
+ /** \OCP\IGroupManager|\PHPUnit_Framework_MockObject_MockObject */
+ $this->groupManager = $this->getMockBuilder('OCP\IGroupManager')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->connection = \OC::$server->getDatabaseConnection();
+
+ $this->deleteAllShares();
+ }
+
+ protected function tearDown() {
+ $this->deleteAllShares();
+
+ parent::tearDown();
+ }
+
+ protected function deleteAllShares() {
+ $qb = $this->connection->getQueryBuilder();
+ $qb->delete('share')->execute();
+ }
+
+ public function testRun() {
+ $repair = new OldGroupMembershipShares(
+ $this->connection,
+ $this->groupManager
+ );
+
+ $this->groupManager->expects($this->exactly(2))
+ ->method('isInGroup')
+ ->willReturnMap([
+ ['member', 'group', true],
+ ['not-a-member', 'group', false],
+ ]);
+
+ $parent = $this->createShare(Constants::SHARE_TYPE_GROUP, 'group', null);
+ $group2 = $this->createShare(Constants::SHARE_TYPE_GROUP, 'group2', $parent);
+ $user1 = $this->createShare(Constants::SHARE_TYPE_USER, 'user1', $parent);
+
+ // \OC\Share\Constant::$shareTypeGroupUserUnique === 2
+ $member = $this->createShare(2, 'member', $parent);
+ $notAMember = $this->createShare(2, 'not-a-member', $parent);
+
+ $query = $this->connection->getQueryBuilder();
+ $result = $query->select('id')
+ ->from('share')
+ ->orderBy('id', 'ASC')
+ ->execute();
+ $rows = $result->fetchAll();
+ $this->assertEquals([['id' => $parent], ['id' => $group2], ['id' => $user1], ['id' => $member], ['id' => $notAMember]], $rows);
+ $result->closeCursor();
+
+ /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */
+ $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $repair->run($outputMock);
+
+ $query = $this->connection->getQueryBuilder();
+ $result = $query->select('id')
+ ->from('share')
+ ->orderBy('id', 'ASC')
+ ->execute();
+ $rows = $result->fetchAll();
+ $this->assertEquals([['id' => $parent], ['id' => $group2], ['id' => $user1], ['id' => $member]], $rows);
+ $result->closeCursor();
+ }
+
+ /**
+ * @param string $shareType
+ * @param string $shareWith
+ * @param null|int $parent
+ * @return int
+ */
+ protected function createShare($shareType, $shareWith, $parent) {
+ $qb = $this->connection->getQueryBuilder();
+ $shareValues = [
+ 'share_type' => $qb->expr()->literal($shareType),
+ 'share_with' => $qb->expr()->literal($shareWith),
+ 'uid_owner' => $qb->expr()->literal('user1'),
+ 'item_type' => $qb->expr()->literal('folder'),
+ 'item_source' => $qb->expr()->literal(123),
+ 'item_target' => $qb->expr()->literal('/123'),
+ 'file_source' => $qb->expr()->literal(123),
+ 'file_target' => $qb->expr()->literal('/test'),
+ 'permissions' => $qb->expr()->literal(1),
+ 'stime' => $qb->expr()->literal(time()),
+ 'expiration' => $qb->expr()->literal('2015-09-25 00:00:00'),
+ ];
+
+ if ($parent) {
+ $shareValues['parent'] = $qb->expr()->literal($parent);
+ }
+
+ $qb = $this->connection->getQueryBuilder();
+ $qb->insert('share')
+ ->values($shareValues)
+ ->execute();
+
+ return $this->connection->lastInsertId('*PREFIX*share');
+ }
+}
diff --git a/tests/lib/Repair/RemoveGetETagEntriesTest.php b/tests/lib/Repair/RemoveGetETagEntriesTest.php
new file mode 100644
index 00000000000..c00923228d0
--- /dev/null
+++ b/tests/lib/Repair/RemoveGetETagEntriesTest.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * @author Morris Jobke <hey@morrisjobke.de>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace Test\Repair;
+
+use OC\Repair\RemoveGetETagEntries;
+use OCP\Migration\IOutput;
+use Test\TestCase;
+
+/**
+ * Class RemoveGetETagEntriesTest
+ *
+ * @group DB
+ *
+ * @package Test\Repair
+ */
+class RemoveGetETagEntriesTest extends TestCase {
+ /** @var \OCP\IDBConnection */
+ protected $connection;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->connection = \OC::$server->getDatabaseConnection();
+ }
+
+ public function testRun() {
+
+ $userName = 'removePropertiesUser';
+ $data = [
+ [$userName, '/abc.def.txt', '{DAV:}getetag', 'abcdef'],
+ [$userName, '/abc.def.txt', '{DAV:}anotherRandomProperty', 'ghi'],
+ ];
+
+ // insert test data
+ $sqlToInsertProperties = 'INSERT INTO `*PREFIX*properties` (`userid`, `propertypath`, `propertyname`, `propertyvalue`) VALUES (?, ?, ? ,?)';
+ foreach ($data as $entry) {
+ $this->connection->executeUpdate($sqlToInsertProperties, $entry);
+ }
+
+ // check if test data is written to DB
+ $sqlToFetchProperties = 'SELECT `userid`, `propertypath`, `propertyname`, `propertyvalue` FROM `*PREFIX*properties` WHERE `userid` = ?';
+ $stmt = $this->connection->executeQuery($sqlToFetchProperties, [$userName]);
+ $entries = $stmt->fetchAll(\PDO::FETCH_NUM);
+
+ $this->assertCount(2, $entries, 'Asserts that two entries are returned as we have inserted two');
+ foreach($entries as $entry) {
+ $this->assertTrue(in_array($entry, $data), 'Asserts that the entries are the ones from the test data set');
+ }
+
+ /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */
+ $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ // run repair step
+ $repair = new RemoveGetETagEntries($this->connection);
+ $repair->run($outputMock);
+
+ // check if test data is correctly modified in DB
+ $stmt = $this->connection->executeQuery($sqlToFetchProperties, [$userName]);
+ $entries = $stmt->fetchAll(\PDO::FETCH_NUM);
+
+ $this->assertCount(1, $entries, 'Asserts that only one entry is returned after the repair step - the other one has to be removed');
+ $this->assertSame($data[1], $entries[0], 'Asserts that the returned entry is the correct one from the test data set');
+
+ // remove test data
+ $sqlToRemoveProperties = 'DELETE FROM `*PREFIX*properties` WHERE `userid` = ?';
+ $this->connection->executeUpdate($sqlToRemoveProperties, [$userName]);
+ }
+
+}
diff --git a/tests/lib/Repair/RepairCollationTest.php b/tests/lib/Repair/RepairCollationTest.php
new file mode 100644
index 00000000000..2e304a74abc
--- /dev/null
+++ b/tests/lib/Repair/RepairCollationTest.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Test\Repair;
+
+use OCP\Migration\IOutput;
+
+/**
+ * Copyright (c) 2014 Thomas Müller <deepdiver@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class TestCollationRepair extends \OC\Repair\Collation {
+ /**
+ * @param \Doctrine\DBAL\Connection $connection
+ * @return string[]
+ */
+ public function getAllNonUTF8BinTables($connection) {
+ return parent::getAllNonUTF8BinTables($connection);
+ }
+}
+
+/**
+ * Tests for the converting of MySQL tables to InnoDB engine
+ *
+ * @group DB
+ *
+ * @see \OC\Repair\RepairMimeTypes
+ */
+class RepairCollationTest extends \Test\TestCase {
+
+ /**
+ * @var TestCollationRepair
+ */
+ private $repair;
+
+ /**
+ * @var \Doctrine\DBAL\Connection
+ */
+ private $connection;
+
+ /**
+ * @var string
+ */
+ private $tableName;
+
+ /**
+ * @var \OCP\IConfig
+ */
+ private $config;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->connection = \OC::$server->getDatabaseConnection();
+ $this->config = \OC::$server->getConfig();
+ if (!$this->connection->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\MySqlPlatform) {
+ $this->markTestSkipped("Test only relevant on MySql");
+ }
+
+ $dbPrefix = $this->config->getSystemValue("dbtableprefix");
+ $this->tableName = $this->getUniqueID($dbPrefix . "_collation_test");
+ $this->connection->exec("CREATE TABLE $this->tableName(text VARCHAR(16)) COLLATE utf8_unicode_ci");
+
+ $this->repair = new TestCollationRepair($this->config, $this->connection);
+ }
+
+ protected function tearDown() {
+ $this->connection->getSchemaManager()->dropTable($this->tableName);
+ parent::tearDown();
+ }
+
+ public function testCollationConvert() {
+ $tables = $this->repair->getAllNonUTF8BinTables($this->connection);
+ $this->assertGreaterThanOrEqual(1, count($tables));
+
+ /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */
+ $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->repair->run($outputMock);
+
+ $tables = $this->repair->getAllNonUTF8BinTables($this->connection);
+ $this->assertCount(0, $tables);
+ }
+}
diff --git a/tests/lib/Repair/RepairInnoDBTest.php b/tests/lib/Repair/RepairInnoDBTest.php
new file mode 100644
index 00000000000..1258dad73f5
--- /dev/null
+++ b/tests/lib/Repair/RepairInnoDBTest.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Copyright (c) 2014 Thomas Müller <deepdiver@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+namespace Test\Repair;
+use OCP\Migration\IOutput;
+use OCP\Migration\IRepairStep;
+
+/**
+ * Tests for the converting of MySQL tables to InnoDB engine
+ *
+ * @group DB
+ *
+ * @see \OC\Repair\RepairMimeTypes
+ */
+class RepairInnoDBTest extends \Test\TestCase {
+
+ /** @var IRepairStep */
+ private $repair;
+
+ /** @var \Doctrine\DBAL\Connection */
+ private $connection;
+
+ /** @var string */
+ private $tableName;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->connection = \OC::$server->getDatabaseConnection();
+ if (!$this->connection->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\MySqlPlatform) {
+ $this->markTestSkipped("Test only relevant on MySql");
+ }
+
+ $dbPrefix = \OC::$server->getConfig()->getSystemValue("dbtableprefix");
+ $this->tableName = $this->getUniqueID($dbPrefix . "_innodb_test");
+ $this->connection->exec("CREATE TABLE $this->tableName(id INT) ENGINE MyISAM");
+
+ $this->repair = new \OC\Repair\InnoDB();
+ }
+
+ protected function tearDown() {
+ $this->connection->getSchemaManager()->dropTable($this->tableName);
+ parent::tearDown();
+ }
+
+ public function testInnoDBConvert() {
+ $result = $this->countMyIsamTables();
+ $this->assertEquals(1, $result);
+
+ /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */
+ $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->repair->run($outputMock);
+
+ $result = $this->countMyIsamTables();
+ $this->assertEquals(0, $result);
+ }
+
+ /**
+ * @param $dbName
+ * @return mixed
+ */
+ private function countMyIsamTables() {
+ $dbName = \OC::$server->getConfig()->getSystemValue("dbname");
+
+ $result = $this->connection->fetchColumn(
+ "SELECT count(*) FROM information_schema.tables WHERE table_schema = ? and table_name = ? AND engine = 'MyISAM'",
+ array($dbName, $this->tableName)
+ );
+ return $result;
+ }
+}
diff --git a/tests/lib/Repair/RepairInvalidSharesTest.php b/tests/lib/Repair/RepairInvalidSharesTest.php
new file mode 100644
index 00000000000..a1e871bcc80
--- /dev/null
+++ b/tests/lib/Repair/RepairInvalidSharesTest.php
@@ -0,0 +1,201 @@
+<?php
+/**
+ * Copyright (c) 2015 Vincent Petry <pvince81@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Repair;
+
+
+use OC\Repair\RepairInvalidShares;
+use OC\Share\Constants;
+use OCP\Migration\IOutput;
+use OCP\Migration\IRepairStep;
+use Test\TestCase;
+
+/**
+ * Tests for repairing invalid shares
+ *
+ * @group DB
+ *
+ * @see \OC\Repair\RepairInvalidShares
+ */
+class RepairInvalidSharesTest extends TestCase {
+
+ /** @var IRepairStep */
+ private $repair;
+
+ /** @var \OCP\IDBConnection */
+ private $connection;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $config = $this->getMockBuilder('OCP\IConfig')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $config->expects($this->any())
+ ->method('getSystemValue')
+ ->with('version')
+ ->will($this->returnValue('8.0.0.0'));
+
+ $this->connection = \OC::$server->getDatabaseConnection();
+ $this->deleteAllShares();
+
+ /** @var \OCP\IConfig $config */
+ $this->repair = new RepairInvalidShares($config, $this->connection);
+ }
+
+ protected function tearDown() {
+ $this->deleteAllShares();
+
+ parent::tearDown();
+ }
+
+ protected function deleteAllShares() {
+ $qb = $this->connection->getQueryBuilder();
+ $qb->delete('share')->execute();
+ }
+
+ /**
+ * Test remove expiration date for non-link shares
+ */
+ public function testRemoveExpirationDateForNonLinkShares() {
+ // user share with bogus expiration date
+ $qb = $this->connection->getQueryBuilder();
+ $qb->insert('share')
+ ->values([
+ 'share_type' => $qb->expr()->literal(Constants::SHARE_TYPE_USER),
+ 'share_with' => $qb->expr()->literal('recipientuser1'),
+ 'uid_owner' => $qb->expr()->literal('user1'),
+ 'item_type' => $qb->expr()->literal('folder'),
+ 'item_source' => $qb->expr()->literal(123),
+ 'item_target' => $qb->expr()->literal('/123'),
+ 'file_source' => $qb->expr()->literal(123),
+ 'file_target' => $qb->expr()->literal('/test'),
+ 'permissions' => $qb->expr()->literal(1),
+ 'stime' => $qb->expr()->literal(time()),
+ 'expiration' => $qb->expr()->literal('2015-09-25 00:00:00')
+ ])
+ ->execute();
+
+ $bogusShareId = $this->getLastShareId();
+
+ // link share with expiration date
+ $qb = $this->connection->getQueryBuilder();
+ $qb->insert('share')
+ ->values([
+ 'share_type' => $qb->expr()->literal(Constants::SHARE_TYPE_LINK),
+ 'uid_owner' => $qb->expr()->literal('user1'),
+ 'item_type' => $qb->expr()->literal('folder'),
+ 'item_source' => $qb->expr()->literal(123),
+ 'item_target' => $qb->expr()->literal('/123'),
+ 'file_source' => $qb->expr()->literal(123),
+ 'file_target' => $qb->expr()->literal('/test'),
+ 'permissions' => $qb->expr()->literal(1),
+ 'stime' => $qb->expr()->literal(time()),
+ 'expiration' => $qb->expr()->literal('2015-09-25 00:00:00'),
+ 'token' => $qb->expr()->literal('abcdefg')
+ ])->execute();
+
+ /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */
+ $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->repair->run($outputMock);
+
+ $results = $this->connection->getQueryBuilder()
+ ->select('*')
+ ->from('share')
+ ->orderBy('share_type', 'ASC')
+ ->execute()
+ ->fetchAll();
+
+ $this->assertCount(2, $results);
+
+ $userShare = $results[0];
+ $linkShare = $results[1];
+ $this->assertEquals($bogusShareId, $userShare['id'], 'sanity check');
+ $this->assertNull($userShare['expiration'], 'bogus expiration date was removed');
+ $this->assertNotNull($linkShare['expiration'], 'valid link share expiration date still there');
+ }
+
+ /**
+ * Test remove shares where the parent share does not exist anymore
+ */
+ public function testSharesNonExistingParent() {
+ $qb = $this->connection->getQueryBuilder();
+ $shareValues = [
+ 'share_type' => $qb->expr()->literal(Constants::SHARE_TYPE_USER),
+ 'share_with' => $qb->expr()->literal('recipientuser1'),
+ 'uid_owner' => $qb->expr()->literal('user1'),
+ 'item_type' => $qb->expr()->literal('folder'),
+ 'item_source' => $qb->expr()->literal(123),
+ 'item_target' => $qb->expr()->literal('/123'),
+ 'file_source' => $qb->expr()->literal(123),
+ 'file_target' => $qb->expr()->literal('/test'),
+ 'permissions' => $qb->expr()->literal(1),
+ 'stime' => $qb->expr()->literal(time()),
+ 'expiration' => $qb->expr()->literal('2015-09-25 00:00:00')
+ ];
+
+ // valid share
+ $qb = $this->connection->getQueryBuilder();
+ $qb->insert('share')
+ ->values($shareValues)
+ ->execute();
+ $parent = $this->getLastShareId();
+
+ // share with existing parent
+ $qb = $this->connection->getQueryBuilder();
+ $qb->insert('share')
+ ->values(array_merge($shareValues, [
+ 'parent' => $qb->expr()->literal($parent),
+ ]))->execute();
+ $validChild = $this->getLastShareId();
+
+ // share with non-existing parent
+ $qb = $this->connection->getQueryBuilder();
+ $qb->insert('share')
+ ->values(array_merge($shareValues, [
+ 'parent' => $qb->expr()->literal($parent + 100),
+ ]))->execute();
+ $invalidChild = $this->getLastShareId();
+
+ $query = $this->connection->getQueryBuilder();
+ $result = $query->select('id')
+ ->from('share')
+ ->orderBy('id', 'ASC')
+ ->execute();
+ $rows = $result->fetchAll();
+ $this->assertEquals([['id' => $parent], ['id' => $validChild], ['id' => $invalidChild]], $rows);
+ $result->closeCursor();
+
+ /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */
+ $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->repair->run($outputMock);
+
+ $query = $this->connection->getQueryBuilder();
+ $result = $query->select('id')
+ ->from('share')
+ ->orderBy('id', 'ASC')
+ ->execute();
+ $rows = $result->fetchAll();
+ $this->assertEquals([['id' => $parent], ['id' => $validChild]], $rows);
+ $result->closeCursor();
+ }
+
+ /**
+ * @return int
+ */
+ protected function getLastShareId() {
+ return $this->connection->lastInsertId('*PREFIX*share');
+ }
+}
+
diff --git a/tests/lib/Repair/RepairLegacyStoragesTest.php b/tests/lib/Repair/RepairLegacyStoragesTest.php
new file mode 100644
index 00000000000..aa51fe06a35
--- /dev/null
+++ b/tests/lib/Repair/RepairLegacyStoragesTest.php
@@ -0,0 +1,335 @@
+<?php
+/**
+ * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Repair;
+
+use OC\Files\Cache\Cache;
+use OC\Files\Cache\Storage;
+use OCP\Migration\IOutput;
+use PHPUnit_Framework_MockObject_MockObject;
+use Test\TestCase;
+
+/**
+ * Tests for the converting of legacy storages to home storages.
+ *
+ * @group DB
+ *
+ * @see \OC\Repair\RepairLegacyStorages
+ */
+class RepairLegacyStoragesTest extends TestCase {
+ /** @var \OCP\IDBConnection */
+ private $connection;
+ /** @var \OCP\IConfig */
+ private $config;
+ private $user;
+ /** @var \OC\Repair\RepairLegacyStorages */
+ private $repair;
+
+ private $dataDir;
+ private $oldDataDir;
+
+ private $legacyStorageId;
+ private $newStorageId;
+
+ /** @var IOutput | PHPUnit_Framework_MockObject_MockObject */
+ private $outputMock;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->config = \OC::$server->getConfig();
+ $this->connection = \OC::$server->getDatabaseConnection();
+ $this->oldDataDir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/');
+
+ $this->repair = new \OC\Repair\RepairLegacyStorages($this->config, $this->connection);
+
+ $this->outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
+ ->disableOriginalConstructor()
+ ->getMock();
+ }
+
+ protected function tearDown() {
+ $user = \OC::$server->getUserManager()->get($this->user);
+ if ($user) {
+ $user->delete();
+ }
+
+ $sql = 'DELETE FROM `*PREFIX*storages`';
+ $this->connection->executeQuery($sql);
+ $sql = 'DELETE FROM `*PREFIX*filecache`';
+ $this->connection->executeQuery($sql);
+ $this->config->setSystemValue('datadirectory', $this->oldDataDir);
+ $this->config->setAppValue('core', 'repairlegacystoragesdone', 'no');
+
+ parent::tearDown();
+ }
+
+ /**
+ * @param string $dataDir
+ * @param string $userId
+ * @throws \Exception
+ */
+ function prepareSettings($dataDir, $userId) {
+ // hard-coded string as we want a predictable fixed length
+ // no data will be written there
+ $this->dataDir = $dataDir;
+ $this->config->setSystemValue('datadirectory', $this->dataDir);
+
+ $this->user = $userId;
+ $this->legacyStorageId = 'local::' . $this->dataDir . $this->user . '/';
+ $this->newStorageId = 'home::' . $this->user;
+ \OC::$server->getUserManager()->createUser($this->user, $this->user);
+ }
+
+ /**
+ * Create a storage entry
+ *
+ * @param string $storageId
+ * @return int
+ */
+ private function createStorage($storageId) {
+ $sql = 'INSERT INTO `*PREFIX*storages` (`id`)'
+ . ' VALUES (?)';
+
+ $storageId = Storage::adjustStorageId($storageId);
+ $numRows = $this->connection->executeUpdate($sql, array($storageId));
+ $this->assertEquals(1, $numRows);
+
+ return \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*storages');
+ }
+
+ /**
+ * Returns the storage id based on the numeric id
+ *
+ * @param int $storageId numeric id of the storage
+ * @return string storage id or null if not found
+ */
+ private function getStorageId($storageId) {
+ $numericId = Storage::getNumericStorageId($storageId);
+ if (!is_null($numericId)) {
+ return (int)$numericId;
+ }
+ return null;
+ }
+
+ /**
+ * Create dummy data in the filecache for the given storage numeric id
+ *
+ * @param string $storageId storage id
+ */
+ private function createData($storageId) {
+ $cache = new Cache($storageId);
+ $cache->put(
+ 'dummyfile.txt',
+ array('size' => 5, 'mtime' => 12, 'mimetype' => 'text/plain')
+ );
+ }
+
+ /**
+ * Test that existing home storages are left alone when valid.
+ *
+ * @dataProvider settingsProvider
+ *
+ * @param string $dataDir
+ * @param string $userId
+ */
+ public function testNoopWithExistingHomeStorage($dataDir, $userId) {
+ $this->prepareSettings($dataDir, $userId);
+ $newStorageNumId = $this->createStorage($this->newStorageId);
+
+ $this->repair->run($this->outputMock);
+
+ $this->assertNull($this->getStorageId($this->legacyStorageId));
+ $this->assertEquals($newStorageNumId, $this->getStorageId($this->newStorageId));
+ }
+
+ /**
+ * Test that legacy storages are converted to home storages when
+ * the latter does not exist.
+ *
+ * @dataProvider settingsProvider
+ *
+ * @param string $dataDir
+ * @param string $userId
+ */
+ public function testConvertLegacyToHomeStorage($dataDir, $userId) {
+ $this->prepareSettings($dataDir, $userId);
+ $legacyStorageNumId = $this->createStorage($this->legacyStorageId);
+
+ $this->repair->run($this->outputMock);
+
+ $this->assertNull($this->getStorageId($this->legacyStorageId));
+ $this->assertEquals($legacyStorageNumId, $this->getStorageId($this->newStorageId));
+ }
+
+ /**
+ * Test that legacy storages are converted to home storages
+ * when home storage already exists but has no data.
+ *
+ * @dataProvider settingsProvider
+ *
+ * @param string $dataDir
+ * @param string $userId
+ */
+ public function testConvertLegacyToExistingEmptyHomeStorage($dataDir, $userId) {
+ $this->prepareSettings($dataDir, $userId);
+ $legacyStorageNumId = $this->createStorage($this->legacyStorageId);
+ $this->createStorage($this->newStorageId);
+
+ $this->createData($this->legacyStorageId);
+
+ $this->repair->run($this->outputMock);
+
+ $this->assertNull($this->getStorageId($this->legacyStorageId));
+ $this->assertEquals($legacyStorageNumId, $this->getStorageId($this->newStorageId));
+ }
+
+ /**
+ * Test that legacy storages are converted to home storages
+ * when home storage already exists and the legacy storage
+ * has no data.
+ *
+ * @dataProvider settingsProvider
+ *
+ * @param string $dataDir
+ * @param string $userId
+ */
+ public function testConvertEmptyLegacyToHomeStorage($dataDir, $userId) {
+ $this->prepareSettings($dataDir, $userId);
+ $this->createStorage($this->legacyStorageId);
+ $newStorageNumId = $this->createStorage($this->newStorageId);
+
+ $this->createData($this->newStorageId);
+
+ $this->repair->run($this->outputMock);
+
+ $this->assertNull($this->getStorageId($this->legacyStorageId));
+ $this->assertEquals($newStorageNumId, $this->getStorageId($this->newStorageId));
+ }
+
+ /**
+ * Test that nothing is done when both conflicting legacy
+ * and home storage have data.
+ *
+ * @dataProvider settingsProvider
+ *
+ * @param string $dataDir
+ * @param string $userId
+ */
+ public function testConflictNoop($dataDir, $userId) {
+ $this->prepareSettings($dataDir, $userId);
+ $legacyStorageNumId = $this->createStorage($this->legacyStorageId);
+ $newStorageNumId = $this->createStorage($this->newStorageId);
+
+ $this->createData($this->legacyStorageId);
+ $this->createData($this->newStorageId);
+
+ $this->outputMock->expects($this->exactly(2))->method('warning');
+ $this->repair->run($this->outputMock);
+
+ // storages left alone
+ $this->assertEquals($legacyStorageNumId, $this->getStorageId($this->legacyStorageId));
+ $this->assertEquals($newStorageNumId, $this->getStorageId($this->newStorageId));
+
+ // do not set the done flag
+ $this->assertNotEquals('yes', $this->config->getAppValue('core', 'repairlegacystoragesdone'));
+ }
+
+ /**
+ * Test that the data dir local entry is left alone
+ *
+ * @dataProvider settingsProvider
+ *
+ * @param string $dataDir
+ * @param string $userId
+ */
+ public function testDataDirEntryNoop($dataDir, $userId) {
+ $this->prepareSettings($dataDir, $userId);
+ $storageId = 'local::' . $this->dataDir;
+ $numId = $this->createStorage($storageId);
+
+ $this->repair->run($this->outputMock);
+
+ $this->assertEquals($numId, $this->getStorageId($storageId));
+ }
+
+ /**
+ * Test that external local storages are left alone
+ *
+ * @dataProvider settingsProvider
+ *
+ * @param string $dataDir
+ * @param string $userId
+ */
+ public function testLocalExtStorageNoop($dataDir, $userId) {
+ $this->prepareSettings($dataDir, $userId);
+ $storageId = 'local::/tmp/somedir/' . $this->user;
+ $numId = $this->createStorage($storageId);
+
+ $this->repair->run($this->outputMock);
+
+ $this->assertEquals($numId, $this->getStorageId($storageId));
+ }
+
+ /**
+ * Test that other external storages are left alone
+ *
+ * @dataProvider settingsProvider
+ *
+ * @param string $dataDir
+ * @param string $userId
+ */
+ public function testExtStorageNoop($dataDir, $userId) {
+ $this->prepareSettings($dataDir, $userId);
+ $storageId = 'smb::user@password/tmp/somedir/' . $this->user;
+ $numId = $this->createStorage($storageId);
+
+ $this->repair->run($this->outputMock);
+
+ $this->assertEquals($numId, $this->getStorageId($storageId));
+ }
+
+ /**
+ * Provides data dir and user name
+ */
+ function settingsProvider() {
+ return array(
+ // regular data dir
+ array(
+ '/tmp/oc-autotest/datadir/',
+ $this->getUniqueID('user_'),
+ ),
+ // long datadir / short user
+ array(
+ '/tmp/oc-autotest/datadir01234567890123456789012345678901234567890123456789END/',
+ $this->getUniqueID('user_'),
+ ),
+ // short datadir / long user
+ array(
+ '/tmp/oc-autotest/datadir/',
+ 'u123456789012345678901234567890123456789012345678901234567890END', // 64 chars
+ ),
+ );
+ }
+
+ /**
+ * Only run the repair once
+ */
+ public function testOnlyRunOnce() {
+ $this->outputMock->expects($this->exactly(1))->method('info');
+
+ $this->prepareSettings('/tmp/oc-autotest/datadir', $this->getUniqueID('user_'));
+ $this->assertNotEquals('yes', $this->config->getAppValue('core', 'repairlegacystoragesdone'));
+ $this->repair->run($this->outputMock);
+ $this->assertEquals('yes', $this->config->getAppValue('core', 'repairlegacystoragesdone'));
+
+ $this->outputMock->expects($this->never())->method('info');
+ $this->repair->run($this->outputMock);
+ $this->assertEquals('yes', $this->config->getAppValue('core', 'repairlegacystoragesdone'));
+ }
+}
diff --git a/tests/lib/Repair/RepairMimeTypesTest.php b/tests/lib/Repair/RepairMimeTypesTest.php
new file mode 100644
index 00000000000..6a42b016938
--- /dev/null
+++ b/tests/lib/Repair/RepairMimeTypesTest.php
@@ -0,0 +1,582 @@
+<?php
+/**
+ * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
+ * Copyright (c) 2014-2015 Olivier Paroz owncloud@oparoz.com
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+namespace Test\Repair;
+
+use OC\Files\Storage\Temporary;
+use OCP\Files\IMimeTypeLoader;
+use OCP\IConfig;
+use OCP\Migration\IOutput;
+use OCP\Migration\IRepairStep;
+
+/**
+ * Tests for the converting of legacy storages to home storages.
+ *
+ * @group DB
+ *
+ * @see \OC\Repair\RepairMimeTypes
+ */
+class RepairMimeTypesTest extends \Test\TestCase {
+
+ /** @var IRepairStep */
+ private $repair;
+
+ /** @var Temporary */
+ private $storage;
+
+ /** @var IMimeTypeLoader */
+ private $mimetypeLoader;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->savedMimetypeLoader = \OC::$server->getMimeTypeLoader();
+ $this->mimetypeLoader = \OC::$server->getMimeTypeLoader();
+
+ /** @var IConfig | \PHPUnit_Framework_MockObject_MockObject $config */
+ $config = $this->getMockBuilder('OCP\IConfig')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $config->expects($this->any())
+ ->method('getSystemValue')
+ ->with('version')
+ ->will($this->returnValue('8.0.0.0'));
+
+ $this->storage = new \OC\Files\Storage\Temporary([]);
+
+ $this->repair = new \OC\Repair\RepairMimeTypes($config);
+ }
+
+ protected function tearDown() {
+ $this->storage->getCache()->clear();
+ $sql = 'DELETE FROM `*PREFIX*storages` WHERE `id` = ?';
+ \OC_DB::executeAudited($sql, [$this->storage->getId()]);
+ $this->clearMimeTypes();
+
+ parent::tearDown();
+ }
+
+ private function clearMimeTypes() {
+ $sql = 'DELETE FROM `*PREFIX*mimetypes`';
+ \OC_DB::executeAudited($sql);
+ $this->mimetypeLoader->reset();
+ }
+
+ private function addEntries($entries) {
+ // create files for the different extensions, this
+ // will also automatically create the corresponding mime types
+ foreach ($entries as $entry) {
+ $this->storage->getCache()->put(
+ $entry[0],
+ [
+ 'size' => 0,
+ 'mtime' => 0,
+ 'mimetype' => $entry[1]
+ ]
+ );
+ }
+
+ }
+
+ private function checkEntries($entries) {
+ foreach ($entries as $entry) {
+ $data = $this->storage->getCache()->get($entry[0]);
+ $this->assertEquals($entry[1], $data['mimetype']);
+ }
+ }
+
+ /**
+ * Returns the id of a given mime type or null
+ * if it does not exist.
+ */
+ private function getMimeTypeIdFromDB($mimeType) {
+ $sql = 'SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?';
+ $results = \OC_DB::executeAudited($sql, [$mimeType]);
+ $result = $results->fetchOne();
+ if ($result) {
+ return $result['id'];
+ }
+ return null;
+ }
+
+ private function renameMimeTypes($currentMimeTypes, $fixedMimeTypes) {
+ $this->addEntries($currentMimeTypes);
+
+ /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */
+ $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->repair->run($outputMock);
+
+ // force mimetype reload
+ $this->mimetypeLoader->reset();
+
+ $this->checkEntries($fixedMimeTypes);
+ }
+
+ /**
+ * Test renaming and splitting old office mime types
+ */
+ public function testRenameOfficeMimeTypes() {
+ $currentMimeTypes = [
+ ['test.doc', 'application/msword'],
+ ['test.docx', 'application/msword'],
+ ['test.xls', 'application/msexcel'],
+ ['test.xlsx', 'application/msexcel'],
+ ['test.ppt', 'application/mspowerpoint'],
+ ['test.pptx', 'application/mspowerpoint'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.doc', 'application/msword'],
+ ['test.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
+ ['test.xls', 'application/vnd.ms-excel'],
+ ['test.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
+ ['test.ppt', 'application/vnd.ms-powerpoint'],
+ ['test.pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+ }
+
+ /**
+ * Test renaming old fonts mime types
+ */
+ public function testRenameFontsMimeTypes() {
+ $currentMimeTypes = [
+ ['test.ttf', 'application/x-font-ttf'],
+ ['test.otf', 'font/opentype'],
+ ['test.pfb', 'application/octet-stream'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.ttf', 'application/font-sfnt'],
+ ['test.otf', 'application/font-sfnt'],
+ ['test.pfb', 'application/x-font'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+ }
+
+ /**
+ * Test renaming the APK mime type
+ */
+ public function testRenameAPKMimeType() {
+ $currentMimeTypes = [
+ ['test.apk', 'application/octet-stream'],
+ ['bogus.apk', 'application/vnd.android.package-archive'],
+ ['bogus2.apk', 'application/wrong'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.apk', 'application/vnd.android.package-archive'],
+ ['bogus.apk', 'application/vnd.android.package-archive'],
+ ['bogus2.apk', 'application/vnd.android.package-archive'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+ }
+
+ /**
+ * Test renaming the postscript mime types
+ */
+ public function testRenamePostscriptMimeType() {
+ $currentMimeTypes = [
+ ['test.eps', 'application/octet-stream'],
+ ['test.ps', 'application/octet-stream'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.eps', 'application/postscript'],
+ ['test.ps', 'application/postscript'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+ }
+
+ /**
+ * Test renaming the Raw mime types
+ */
+ public function testRenameRawMimeType() {
+ $currentMimeTypes = [
+ ['test.arw', 'application/octet-stream'],
+ ['test.cr2', 'application/octet-stream'],
+ ['test.dcr', 'application/octet-stream'],
+ ['test.dng', 'application/octet-stream'],
+ ['test.erf', 'application/octet-stream'],
+ ['test.iiq', 'application/octet-stream'],
+ ['test.k25', 'application/octet-stream'],
+ ['test.kdc', 'application/octet-stream'],
+ ['test.mef', 'application/octet-stream'],
+ ['test.nef', 'application/octet-stream'],
+ ['test.orf', 'application/octet-stream'],
+ ['test.pef', 'application/octet-stream'],
+ ['test.raf', 'application/octet-stream'],
+ ['test.rw2', 'application/octet-stream'],
+ ['test.srf', 'application/octet-stream'],
+ ['test.sr2', 'application/octet-stream'],
+ ['test.xrf', 'application/octet-stream'],
+ ['CapitalExtension.DNG', 'application/octet-stream'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.arw', 'image/x-dcraw'],
+ ['test.cr2', 'image/x-dcraw'],
+ ['test.dcr', 'image/x-dcraw'],
+ ['test.dng', 'image/x-dcraw'],
+ ['test.erf', 'image/x-dcraw'],
+ ['test.iiq', 'image/x-dcraw'],
+ ['test.k25', 'image/x-dcraw'],
+ ['test.kdc', 'image/x-dcraw'],
+ ['test.mef', 'image/x-dcraw'],
+ ['test.nef', 'image/x-dcraw'],
+ ['test.orf', 'image/x-dcraw'],
+ ['test.pef', 'image/x-dcraw'],
+ ['test.raf', 'image/x-dcraw'],
+ ['test.rw2', 'image/x-dcraw'],
+ ['test.srf', 'image/x-dcraw'],
+ ['test.sr2', 'image/x-dcraw'],
+ ['test.xrf', 'image/x-dcraw'],
+ ['CapitalExtension.DNG', 'image/x-dcraw'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+ }
+
+ /**
+ * Test renaming the 3D image media type
+ */
+ public function testRename3dImagesMimeType() {
+ $currentMimeTypes = [
+ ['test.jps', 'application/octet-stream'],
+ ['test.mpo', 'application/octet-stream'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.jps', 'image/jpeg'],
+ ['test.mpo', 'image/jpeg'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+ }
+
+ /**
+ * Test renaming the conf/cnf media type
+ */
+ public function testRenameConfMimeType() {
+ $currentMimeTypes = [
+ ['test.conf', 'application/octet-stream'],
+ ['test.cnf', 'application/octet-stream'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.conf', 'text/plain'],
+ ['test.cnf', 'text/plain'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+ }
+
+ /**
+ * Test renaming the yaml media type
+ */
+ public function testRenameYamlMimeType() {
+ $currentMimeTypes = [
+ ['test.yaml', 'application/octet-stream'],
+ ['test.yml', 'application/octet-stream'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.yaml', 'application/yaml'],
+ ['test.yml', 'application/yaml'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+ }
+
+ /**
+ * Test renaming the java mime types
+ */
+ public function testRenameJavaMimeType() {
+ $currentMimeTypes = [
+ ['test.java', 'application/octet-stream'],
+ ['test.class', 'application/octet-stream'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.java', 'text/x-java-source'],
+ ['test.class', 'application/java'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+ }
+
+ /**
+ * Test renaming the hpp mime type
+ */
+ public function testRenameHppMimeType() {
+ $currentMimeTypes = [
+ ['test.hpp', 'application/octet-stream'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.hpp', 'text/x-h'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+ }
+
+ /**
+ * Test renaming the rss mime type
+ */
+ public function testRenameRssMimeType() {
+ $currentMimeTypes = [
+ ['test.rss', 'application/octet-stream'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.rss', 'application/rss+xml'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+ }
+
+ /**
+ * Test renaming the hpp mime type
+ */
+ public function testRenameRtfMimeType() {
+ $currentMimeTypes = [
+ ['test.rtf', 'application/octet-stream'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.rtf', 'text/rtf'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+ }
+
+ /**
+ * Test renaming the richdocuments additional office mime types
+ */
+ public function testRenameRichDocumentsMimeTypes() {
+ $currentMimeTypes = [
+ ['test.lwp', 'application/octet-stream'],
+ ['test.one', 'application/octet-stream'],
+ ['test.vsd', 'application/octet-stream'],
+ ['test.wpd', 'application/octet-stream'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.lwp', 'application/vnd.lotus-wordpro'],
+ ['test.one', 'application/msonenote'],
+ ['test.vsd', 'application/vnd.visio'],
+ ['test.wpd', 'application/vnd.wordperfect'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+ }
+
+ /**
+ * Test renaming and splitting old office mime types when
+ * new ones already exist
+ */
+ public function testRenameOfficeMimeTypesWhenExist() {
+ $currentMimeTypes = [
+ ['test.doc', 'application/msword'],
+ ['test.docx', 'application/msword'],
+ ['test.xls', 'application/msexcel'],
+ ['test.xlsx', 'application/msexcel'],
+ ['test.ppt', 'application/mspowerpoint'],
+ ['test.pptx', 'application/mspowerpoint'],
+ // make it so that the new mimetypes already exist
+ ['bogus.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
+ ['bogus.xlsx', 'application/vnd.ms-excel'],
+ ['bogus.pptx', 'application/vnd.ms-powerpoint'],
+ ['bogus2.docx', 'application/wrong'],
+ ['bogus2.xlsx', 'application/wrong'],
+ ['bogus2.pptx', 'application/wrong'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.doc', 'application/msword'],
+ ['test.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
+ ['test.xls', 'application/vnd.ms-excel'],
+ ['test.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
+ ['test.ppt', 'application/vnd.ms-powerpoint'],
+ ['test.pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'],
+ ['bogus.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
+ ['bogus.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
+ ['bogus.pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'],
+ ['bogus2.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
+ ['bogus2.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
+ ['bogus2.pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+
+ // wrong mimetypes are gone
+ $this->assertNull($this->getMimeTypeIdFromDB('application/msexcel'));
+ $this->assertNull($this->getMimeTypeIdFromDB('application/mspowerpoint'));
+ }
+
+ /**
+ * Test renaming old fonts mime types when
+ * new ones already exist
+ */
+ public function testRenameFontsMimeTypesWhenExist() {
+ $currentMimeTypes = [
+ ['test.ttf', 'application/x-font-ttf'],
+ ['test.otf', 'font/opentype'],
+ // make it so that the new mimetypes already exist
+ ['bogus.ttf', 'application/font-sfnt'],
+ ['bogus.otf', 'application/font-sfnt'],
+ ['bogus2.ttf', 'application/wrong'],
+ ['bogus2.otf', 'application/wrong'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.ttf', 'application/font-sfnt'],
+ ['test.otf', 'application/font-sfnt'],
+ ['bogus.ttf', 'application/font-sfnt'],
+ ['bogus.otf', 'application/font-sfnt'],
+ ['bogus2.ttf', 'application/font-sfnt'],
+ ['bogus2.otf', 'application/font-sfnt'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+
+ // wrong mimetypes are gone
+ $this->assertNull($this->getMimeTypeIdFromDB('application/x-font-ttf'));
+ $this->assertNull($this->getMimeTypeIdFromDB('font'));
+ $this->assertNull($this->getMimeTypeIdFromDB('font/opentype'));
+ }
+
+ /**
+ * Test that nothing happens and no error happens when all mimetypes are
+ * already correct and no old ones exist..
+ */
+ public function testDoNothingWhenOnlyNewFiles() {
+ $currentMimeTypes = [
+ ['test.doc', 'application/msword'],
+ ['test.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
+ ['test.xls', 'application/vnd.ms-excel'],
+ ['test.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
+ ['test.ppt', 'application/vnd.ms-powerpoint'],
+ ['test.pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'],
+ ['test.apk', 'application/vnd.android.package-archive'],
+ ['test.ttf', 'application/font-sfnt'],
+ ['test.otf', 'application/font-sfnt'],
+ ['test.pfb', 'application/x-font'],
+ ['test.eps', 'application/postscript'],
+ ['test.ps', 'application/postscript'],
+ ['test.arw', 'image/x-dcraw'],
+ ['test.cr2', 'image/x-dcraw'],
+ ['test.dcr', 'image/x-dcraw'],
+ ['test.dng', 'image/x-dcraw'],
+ ['test.erf', 'image/x-dcraw'],
+ ['test.iiq', 'image/x-dcraw'],
+ ['test.k25', 'image/x-dcraw'],
+ ['test.kdc', 'image/x-dcraw'],
+ ['test.mef', 'image/x-dcraw'],
+ ['test.nef', 'image/x-dcraw'],
+ ['test.orf', 'image/x-dcraw'],
+ ['test.pef', 'image/x-dcraw'],
+ ['test.raf', 'image/x-dcraw'],
+ ['test.rw2', 'image/x-dcraw'],
+ ['test.srf', 'image/x-dcraw'],
+ ['test.sr2', 'image/x-dcraw'],
+ ['test.xrf', 'image/x-dcraw'],
+ ['test.DNG', 'image/x-dcraw'],
+ ['test.jps', 'image/jpeg'],
+ ['test.MPO', 'image/jpeg'],
+ ['test.conf', 'text/plain'],
+ ['test.cnf', 'text/plain'],
+ ['test.yaml', 'application/yaml'],
+ ['test.yml', 'application/yaml'],
+ ['test.java', 'text/x-java-source'],
+ ['test.class', 'application/java'],
+ ['test.hpp', 'text/x-h'],
+ ['test.rss', 'application/rss+xml'],
+ ['test.rtf', 'text/rtf'],
+ ['test.lwp', 'application/vnd.lotus-wordpro'],
+ ['test.one', 'application/msonenote'],
+ ['test.vsd', 'application/vnd.visio'],
+ ['test.wpd', 'application/vnd.wordperfect'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.doc', 'application/msword'],
+ ['test.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
+ ['test.xls', 'application/vnd.ms-excel'],
+ ['test.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
+ ['test.ppt', 'application/vnd.ms-powerpoint'],
+ ['test.pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'],
+ ['test.apk', 'application/vnd.android.package-archive'],
+ ['test.ttf', 'application/font-sfnt'],
+ ['test.otf', 'application/font-sfnt'],
+ ['test.pfb', 'application/x-font'],
+ ['test.eps', 'application/postscript'],
+ ['test.ps', 'application/postscript'],
+ ['test.arw', 'image/x-dcraw'],
+ ['test.cr2', 'image/x-dcraw'],
+ ['test.dcr', 'image/x-dcraw'],
+ ['test.dng', 'image/x-dcraw'],
+ ['test.erf', 'image/x-dcraw'],
+ ['test.iiq', 'image/x-dcraw'],
+ ['test.k25', 'image/x-dcraw'],
+ ['test.kdc', 'image/x-dcraw'],
+ ['test.mef', 'image/x-dcraw'],
+ ['test.nef', 'image/x-dcraw'],
+ ['test.orf', 'image/x-dcraw'],
+ ['test.pef', 'image/x-dcraw'],
+ ['test.raf', 'image/x-dcraw'],
+ ['test.rw2', 'image/x-dcraw'],
+ ['test.srf', 'image/x-dcraw'],
+ ['test.sr2', 'image/x-dcraw'],
+ ['test.xrf', 'image/x-dcraw'],
+ ['test.DNG', 'image/x-dcraw'],
+ ['test.jps', 'image/jpeg'],
+ ['test.MPO', 'image/jpeg'],
+ ['test.conf', 'text/plain'],
+ ['test.cnf', 'text/plain'],
+ ['test.yaml', 'application/yaml'],
+ ['test.yml', 'application/yaml'],
+ ['test.java', 'text/x-java-source'],
+ ['test.class', 'application/java'],
+ ['test.hpp', 'text/x-h'],
+ ['test.rss', 'application/rss+xml'],
+ ['test.rtf', 'text/rtf'],
+ ['test.lwp', 'application/vnd.lotus-wordpro'],
+ ['test.one', 'application/msonenote'],
+ ['test.vsd', 'application/vnd.visio'],
+ ['test.wpd', 'application/vnd.wordperfect'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+ }
+
+ /**
+ * Test that mime type renaming does not affect folders
+ */
+ public function testDoNotChangeFolderMimeType() {
+ $currentMimeTypes = [
+ ['test.conf', 'httpd/unix-directory'],
+ ['test.cnf', 'httpd/unix-directory'],
+ ];
+
+ $fixedMimeTypes = [
+ ['test.conf', 'httpd/unix-directory'],
+ ['test.cnf', 'httpd/unix-directory'],
+ ];
+
+ $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes);
+ }
+}
+
diff --git a/tests/lib/Repair/RepairSharePropagationTest.php b/tests/lib/Repair/RepairSharePropagationTest.php
new file mode 100644
index 00000000000..07db3c84f28
--- /dev/null
+++ b/tests/lib/Repair/RepairSharePropagationTest.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Copyright (c) 2016 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Repair;
+
+use OC\Repair\SharePropagation;
+use OCP\Migration\IOutput;
+
+class RepairSharePropagationTest extends \Test\TestCase {
+ public function keyProvider() {
+ return [
+ [['1', '2'], ['1', '2']],
+ [['1', '2', 'foo'], ['1', '2']],
+ [['foo'], []],
+ ];
+ }
+
+ /**
+ * @dataProvider keyProvider
+ * @param array $startKeys
+ * @param array $expectedRemovedKeys
+ */
+ public function testRemovePropagationEntries(array $startKeys, array $expectedRemovedKeys) {
+ /** @var \PHPUnit_Framework_MockObject_MockObject|\OCP\IConfig $config */
+ $config = $this->getMock('\OCP\IConfig');
+ $config->expects($this->once())
+ ->method('getAppKeys')
+ ->with('files_sharing')
+ ->will($this->returnValue($startKeys));
+
+ $removedKeys = [];
+
+ $config->expects($this->any())
+ ->method('deleteAppValue')
+ ->will($this->returnCallback(function ($app, $key) use (&$removedKeys) {
+ $removedKeys[] = $key;
+ }));
+
+ /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */
+ $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $step = new SharePropagation($config);
+ $step->run($outputMock);
+
+ sort($expectedRemovedKeys);
+ sort($removedKeys);
+
+ $this->assertEquals($expectedRemovedKeys, $removedKeys);
+ }
+}
diff --git a/tests/lib/Repair/RepairSqliteAutoincrementTest.php b/tests/lib/Repair/RepairSqliteAutoincrementTest.php
new file mode 100644
index 00000000000..22186283779
--- /dev/null
+++ b/tests/lib/Repair/RepairSqliteAutoincrementTest.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Copyright (c) 2015 Vincent Petry <pvince81@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Repair;
+use OCP\Migration\IOutput;
+
+/**
+ * Tests for fixing the SQLite id recycling
+ *
+ * @group DB
+ */
+class RepairSqliteAutoincrementTest extends \Test\TestCase {
+
+ /**
+ * @var \OC\Repair\SqliteAutoincrement
+ */
+ private $repair;
+
+ /**
+ * @var \Doctrine\DBAL\Connection
+ */
+ private $connection;
+
+ /**
+ * @var string
+ */
+ private $tableName;
+
+ /**
+ * @var \OCP\IConfig
+ */
+ private $config;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->connection = \OC::$server->getDatabaseConnection();
+ $this->config = \OC::$server->getConfig();
+ if (!$this->connection->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SqlitePlatform) {
+ $this->markTestSkipped("Test only relevant on Sqlite");
+ }
+
+ $dbPrefix = $this->config->getSystemValue('dbtableprefix', 'oc_');
+ $this->tableName = $this->getUniqueID($dbPrefix . 'autoinc_test');
+ $this->connection->exec('CREATE TABLE ' . $this->tableName . '("someid" INTEGER NOT NULL, "text" VARCHAR(16), PRIMARY KEY("someid"))');
+
+ $this->repair = new \OC\Repair\SqliteAutoincrement($this->connection);
+ }
+
+ protected function tearDown() {
+ $this->connection->getSchemaManager()->dropTable($this->tableName);
+ parent::tearDown();
+ }
+
+ /**
+ * Tests whether autoincrement works
+ *
+ * @return boolean true if autoincrement works, false otherwise
+ */
+ protected function checkAutoincrement() {
+ $this->connection->executeUpdate('INSERT INTO ' . $this->tableName . ' ("text") VALUES ("test")');
+ $insertId = $this->connection->lastInsertId();
+ $this->connection->executeUpdate('DELETE FROM ' . $this->tableName . ' WHERE "someid" = ?', array($insertId));
+
+ // insert again
+ $this->connection->executeUpdate('INSERT INTO ' . $this->tableName . ' ("text") VALUES ("test2")');
+ $newInsertId = $this->connection->lastInsertId();
+
+ return ($insertId !== $newInsertId);
+ }
+
+ public function testConvertIdColumn() {
+ $this->assertFalse($this->checkAutoincrement());
+
+ /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */
+ $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->repair->run($outputMock);
+
+ $this->assertTrue($this->checkAutoincrement());
+ }
+}
diff --git a/tests/lib/Repair/UpdateOutdatedOcsIdsTest.php b/tests/lib/Repair/UpdateOutdatedOcsIdsTest.php
new file mode 100644
index 00000000000..eb80e63a202
--- /dev/null
+++ b/tests/lib/Repair/UpdateOutdatedOcsIdsTest.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * @author Lukas Reschke <l8kas@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace Test\Repair;
+
+use OCP\IConfig;
+use Test\TestCase;
+
+/**
+ * Class UpdateOutdatedOcsIds
+ *
+ * @package Test\Repair
+ */
+class UpdateOutdatedOcsIdsTest extends TestCase {
+ /** @var IConfig | \PHPUnit_Framework_MockObject_MockObject */
+ private $config;
+ /** @var \OC\Repair\UpdateOutdatedOcsIds */
+ private $updateOutdatedOcsIds;
+
+ public function setUp() {
+ parent::setUp();
+ $this->config = $this->getMockBuilder('\\OCP\\IConfig')->getMock();
+ $this->updateOutdatedOcsIds = new \OC\Repair\UpdateOutdatedOcsIds($this->config);
+ }
+
+ public function testGetName() {
+ $this->assertSame('Repair outdated OCS IDs', $this->updateOutdatedOcsIds->getName());
+ }
+
+ public function testFixOcsIdNoOcsId() {
+ $this->config
+ ->expects($this->once())
+ ->method('getAppValue')
+ ->with('MyNotInstalledApp', 'ocsid')
+ ->will($this->returnValue(''));
+ $this->assertFalse($this->updateOutdatedOcsIds->fixOcsId('MyNotInstalledApp', '1337', '0815'));
+ }
+
+ public function testFixOcsIdUpdateOcsId() {
+ $this->config
+ ->expects($this->at(0))
+ ->method('getAppValue')
+ ->with('MyInstalledApp', 'ocsid')
+ ->will($this->returnValue('1337'));
+ $this->config
+ ->expects($this->at(1))
+ ->method('setAppValue')
+ ->with('MyInstalledApp', 'ocsid', '0815');
+
+ $this->assertTrue($this->updateOutdatedOcsIds->fixOcsId('MyInstalledApp', '1337', '0815'));
+ }
+
+ public function testFixOcsIdAlreadyFixed() {
+ $this->config
+ ->expects($this->once())
+ ->method('getAppValue')
+ ->with('MyAlreadyFixedAppId', 'ocsid')
+ ->will($this->returnValue('0815'));
+
+ $this->assertFalse($this->updateOutdatedOcsIds->fixOcsId('MyAlreadyFixedAppId', '1337', '0815'));
+ }
+}
diff --git a/tests/lib/Repair/fixtures/dropoldtables.xml b/tests/lib/Repair/fixtures/dropoldtables.xml
new file mode 100644
index 00000000000..6c42a8f90a7
--- /dev/null
+++ b/tests/lib/Repair/fixtures/dropoldtables.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<database>
+
+ <name>*dbname*</name>
+ <create>true</create>
+ <overwrite>false</overwrite>
+
+ <charset>utf8</charset>
+
+ <table>
+
+ <name>*dbprefix*permissions</name>
+
+ <declaration>
+ <field>
+ <name>textfield</name>
+ <type>text</type>
+ <default>foo</default>
+ <notnull>true</notnull>
+ <length>32</length>
+ </field>
+ </declaration>
+ </table>
+</database>