diff --git a/psalm.xml b/psalm.xml
index 68661c2e2..6ba160a9e 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -37,13 +37,17 @@
+
+
+
+
@@ -100,6 +104,8 @@
+
+
diff --git a/tests/stubs/oc_files_setupmanager.php b/tests/stubs/oc_files_setupmanager.php
new file mode 100644
index 000000000..83c40ff76
--- /dev/null
+++ b/tests/stubs/oc_files_setupmanager.php
@@ -0,0 +1,97 @@
+ an array of user ids
+ */
+ public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0): array
+ {
+ }
+
+ public function searchInGroup(string $gid, string $search = '', int $limit = -1, int $offset = 0): array
+ {
+ }
+
+ /**
+ * get the number of all users matching the search string in a group
+ * @param string $gid
+ * @param string $search
+ * @return int
+ */
+ public function countUsersInGroup(string $gid, string $search = ''): int
+ {
+ }
+
+ /**
+ * get the number of disabled users in a group
+ *
+ * @param string $search
+ *
+ * @return int
+ */
+ public function countDisabledInGroup(string $gid): int
+ {
+ }
+
+ public function getDisplayName(string $gid): string
+ {
+ }
+
+ public function getGroupDetails(string $gid): array
+ {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getGroupsDetails(array $gids): array
+ {
+ }
+
+ public function setDisplayName(string $gid, string $displayName): bool
+ {
+ }
+
+ /**
+ * Backend name to be shown in group management
+ * @return string the name of the backend to be shown
+ * @since 21.0.0
+ */
+ public function getBackendName(): string
+ {
+ }
+}
diff --git a/tests/stubs/oc_server.php b/tests/stubs/oc_server.php
index 08927f9b9..f3f822823 100644
--- a/tests/stubs/oc_server.php
+++ b/tests/stubs/oc_server.php
@@ -177,7 +177,6 @@
use OCP\IGroupManager;
use OCP\IInitialStateService;
use OCP\IL10N;
-use OCP\ILogger;
use OCP\INavigationManager;
use OCP\IPhoneNumberUtil;
use OCP\IPreview;
@@ -204,6 +203,7 @@
use OCP\Profiler\IProfiler;
use OCP\Remote\Api\IApiFactory;
use OCP\Remote\IInstanceFactory;
+use OCP\RichObjectStrings\IRichTextFormatter;
use OCP\RichObjectStrings\IValidator;
use OCP\Route\IRouter;
use OCP\Security\Bruteforce\IThrottler;
@@ -594,16 +594,6 @@ public function getActivityManager()
*/
public function getJobList()
{
- }
-
- /**
- * Returns a logger instance
- *
- * @return ILogger
- * @deprecated 20.0.0
- */
- public function getLogger()
- {
}
/**
diff --git a/tests/stubs/test_testcase.php b/tests/stubs/test_testcase.php
new file mode 100644
index 000000000..f85a013f9
--- /dev/null
+++ b/tests/stubs/test_testcase.php
@@ -0,0 +1,255 @@
+=')) {
+ trait OnNotSuccessfulTestTrait {
+ protected function onNotSuccessfulTest(\Throwable $t): never {
+ $this->restoreAllServices();
+
+ // restore database connection
+ if (!$this->IsDatabaseAccessAllowed()) {
+ \OC::$server->registerService(IDBConnection::class, function () {
+ return self::$realDatabase;
+ });
+ }
+
+ parent::onNotSuccessfulTest($t);
+ }
+ }
+} else {
+ trait OnNotSuccessfulTestTrait {
+ protected function onNotSuccessfulTest(\Throwable $t): void {
+ $this->restoreAllServices();
+
+ // restore database connection
+ if (!$this->IsDatabaseAccessAllowed()) {
+ \OC::$server->registerService(IDBConnection::class, function () {
+ return self::$realDatabase;
+ });
+ }
+
+ parent::onNotSuccessfulTest($t);
+ }
+ }
+}
+
+abstract class TestCase extends \PHPUnit\Framework\TestCase {
+ /** @var IDBConnection */
+ protected static $realDatabase = null;
+
+ /** @var array */
+ protected $services = [];
+
+ use OnNotSuccessfulTestTrait;
+
+ /**
+ * @param string $name
+ * @param mixed $newService
+ * @return bool
+ */
+ public function overwriteService(string $name, $newService): bool
+ {
+ }
+
+ /**
+ * @param string $name
+ * @return bool
+ */
+ public function restoreService(string $name): bool
+ {
+ }
+
+ public function restoreAllServices()
+ {
+ }
+
+ protected function getTestTraits()
+ {
+ }
+
+ protected function setUp(): void
+ {
+ }
+
+ protected function tearDown(): void
+ {
+ }
+
+ /**
+ * Allows us to test private methods/properties
+ *
+ * @param $object
+ * @param $methodName
+ * @param array $parameters
+ * @return mixed
+ */
+ protected static function invokePrivate($object, $methodName, array $parameters = [])
+ {
+ }
+
+ /**
+ * Returns a unique identifier as uniqid() is not reliable sometimes
+ *
+ * @param string $prefix
+ * @param int $length
+ * @return string
+ */
+ protected static function getUniqueID($prefix = '', $length = 13)
+ {
+ }
+
+ public static function tearDownAfterClass(): void
+ {
+ }
+
+ /**
+ * Remove all entries from the share table
+ *
+ * @param IQueryBuilder $queryBuilder
+ */
+ protected static function tearDownAfterClassCleanShares(IQueryBuilder $queryBuilder)
+ {
+ }
+
+ /**
+ * Remove all entries from the storages table
+ *
+ * @param IQueryBuilder $queryBuilder
+ */
+ protected static function tearDownAfterClassCleanStorages(IQueryBuilder $queryBuilder)
+ {
+ }
+
+ /**
+ * Remove all entries from the filecache table
+ *
+ * @param IQueryBuilder $queryBuilder
+ */
+ protected static function tearDownAfterClassCleanFileCache(IQueryBuilder $queryBuilder)
+ {
+ }
+
+ /**
+ * Remove all unused files from the data dir
+ *
+ * @param string $dataDir
+ */
+ protected static function tearDownAfterClassCleanStrayDataFiles($dataDir)
+ {
+ }
+
+ /**
+ * Recursive delete files and folders from a given directory
+ *
+ * @param string $dir
+ */
+ protected static function tearDownAfterClassCleanStrayDataUnlinkDir($dir)
+ {
+ }
+
+ /**
+ * Clean up the list of hooks
+ */
+ protected static function tearDownAfterClassCleanStrayHooks()
+ {
+ }
+
+ /**
+ * Clean up the list of locks
+ */
+ protected static function tearDownAfterClassCleanStrayLocks()
+ {
+ }
+
+ /**
+ * Login and setup FS as a given user,
+ * sets the given user as the current user.
+ *
+ * @param string $user user id or empty for a generic FS
+ */
+ protected static function loginAsUser($user = '')
+ {
+ }
+
+ /**
+ * Logout the current user and tear down the filesystem.
+ */
+ protected static function logout()
+ {
+ }
+
+ /**
+ * Run all commands pushed to the bus
+ */
+ protected function runCommands()
+ {
+ }
+
+ /**
+ * Check if the given path is locked with a given type
+ *
+ * @param \OC\Files\View $view view
+ * @param string $path path to check
+ * @param int $type lock type
+ * @param bool $onMountPoint true to check the mount point instead of the
+ * mounted storage
+ *
+ * @return boolean true if the file is locked with the
+ * given type, false otherwise
+ */
+ protected function isFileLocked($view, $path, $type, $onMountPoint = false)
+ {
+ }
+
+ protected function getGroupAnnotations(): array
+ {
+ }
+
+ protected function IsDatabaseAccessAllowed()
+ {
+ }
+
+ /**
+ * @param string $expectedHtml
+ * @param string $template
+ * @param array $vars
+ */
+ protected function assertTemplate($expectedHtml, $template, $vars = [])
+ {
+ }
+
+ /**
+ * @param string $expectedHtml
+ * @param string $actualHtml
+ * @param string $message
+ */
+ protected function assertHtmlStringEqualsHtmlString($expectedHtml, $actualHtml, $message = '')
+ {
+ }
+}
diff --git a/tests/stubs/test_traits_usertrait.php b/tests/stubs/test_traits_usertrait.php
new file mode 100644
index 000000000..365813948
--- /dev/null
+++ b/tests/stubs/test_traits_usertrait.php
@@ -0,0 +1,45 @@
+uid = $uid;
+ }
+
+ public function getUID(): string {
+ return $this->uid;
+ }
+}
+
+/**
+ * Allow creating users in a temporary backend
+ */
+trait UserTrait {
+ /**
+ * @var \Test\Util\User\Dummy|\OCP\UserInterface
+ */
+ protected $userBackend;
+
+ protected function createUser($name, $password): IUser
+ {
+ }
+
+ protected function setUpUserTrait()
+ {
+ }
+
+ protected function tearDownUserTrait()
+ {
+ }
+}