Completed
Push — master ( 5d14f8...2337bd )
by Robin
27:19 queued 16s
created
build/rector.php 1 patch
Indentation   +75 added lines, -75 removed lines patch added patch discarded remove patch
@@ -21,79 +21,79 @@  discard block
 block discarded – undo
21 21
 $nextcloudDir = dirname(__DIR__);
22 22
 
23 23
 class NextcloudNamespaceSkipVoter implements ClassNameImportSkipVoterInterface {
24
-	private array $namespacePrefixes = [
25
-		'OC',
26
-		'OCA',
27
-		'OCP',
28
-	];
29
-	private array $skippedClassNames = [
30
-		'Backend',
31
-		'Connection',
32
-		'Exception',
33
-		'IManager',
34
-		'IProvider',
35
-		'Manager',
36
-		'Plugin',
37
-		'Provider',
38
-	];
39
-	public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedObjectType, Node $node) : bool {
40
-		if (in_array($fullyQualifiedObjectType->getShortName(), $this->skippedClassNames)) {
41
-			// Skip common class names to avoid confusion
42
-			return true;
43
-		}
44
-		foreach ($this->namespacePrefixes as $prefix) {
45
-			if (str_starts_with($fullyQualifiedObjectType->getClassName(), $prefix . '\\')) {
46
-				// Import Nextcloud namespaces
47
-				return false;
48
-			}
49
-		}
50
-		// Skip everything else
51
-		return true;
52
-	}
24
+    private array $namespacePrefixes = [
25
+        'OC',
26
+        'OCA',
27
+        'OCP',
28
+    ];
29
+    private array $skippedClassNames = [
30
+        'Backend',
31
+        'Connection',
32
+        'Exception',
33
+        'IManager',
34
+        'IProvider',
35
+        'Manager',
36
+        'Plugin',
37
+        'Provider',
38
+    ];
39
+    public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedObjectType, Node $node) : bool {
40
+        if (in_array($fullyQualifiedObjectType->getShortName(), $this->skippedClassNames)) {
41
+            // Skip common class names to avoid confusion
42
+            return true;
43
+        }
44
+        foreach ($this->namespacePrefixes as $prefix) {
45
+            if (str_starts_with($fullyQualifiedObjectType->getClassName(), $prefix . '\\')) {
46
+                // Import Nextcloud namespaces
47
+                return false;
48
+            }
49
+        }
50
+        // Skip everything else
51
+        return true;
52
+    }
53 53
 }
54 54
 
55 55
 $config = RectorConfig::configure()
56
-	->withPaths([
57
-		$nextcloudDir . '/apps',
58
-		$nextcloudDir . '/core',
59
-		$nextcloudDir . '/ocs',
60
-		$nextcloudDir . '/ocs-provider',
61
-		$nextcloudDir . '/console.php',
62
-		$nextcloudDir . '/cron.php',
63
-		$nextcloudDir . '/index.php',
64
-		$nextcloudDir . '/occ',
65
-		$nextcloudDir . '/public.php',
66
-		$nextcloudDir . '/remote.php',
67
-		$nextcloudDir . '/status.php',
68
-		$nextcloudDir . '/version.php',
69
-		$nextcloudDir . '/lib/private/Share20/ProviderFactory.php',
70
-		$nextcloudDir . '/tests',
71
-		// $nextcloudDir . '/config',
72
-		// $nextcloudDir . '/lib',
73
-		// $nextcloudDir . '/themes',
74
-	])
75
-	->withSkip([
76
-		$nextcloudDir . '/apps/*/3rdparty/*',
77
-		$nextcloudDir . '/apps/*/build/stubs/*',
78
-		$nextcloudDir . '/apps/*/composer/*',
79
-		$nextcloudDir . '/apps/*/config/*',
80
-	])
81
-	// uncomment to reach your current PHP version
82
-	// ->withPhpSets()
83
-	->withImportNames(importShortClasses:false)
84
-	->withTypeCoverageLevel(0)
85
-	->withRules([
86
-		UseSpecificWillMethodRector::class,
87
-		StaticDataProviderClassMethodRector::class,
88
-		DataProviderAnnotationToAttributeRector::class,
89
-	])
90
-	->withConfiguredRule(ClassPropertyAssignToConstructorPromotionRector::class, [
91
-		'inline_public' => true,
92
-		'rename_property' => true,
93
-	])
94
-	->withSets([
95
-		NextcloudSets::NEXTCLOUD_25,
96
-	]);
56
+    ->withPaths([
57
+        $nextcloudDir . '/apps',
58
+        $nextcloudDir . '/core',
59
+        $nextcloudDir . '/ocs',
60
+        $nextcloudDir . '/ocs-provider',
61
+        $nextcloudDir . '/console.php',
62
+        $nextcloudDir . '/cron.php',
63
+        $nextcloudDir . '/index.php',
64
+        $nextcloudDir . '/occ',
65
+        $nextcloudDir . '/public.php',
66
+        $nextcloudDir . '/remote.php',
67
+        $nextcloudDir . '/status.php',
68
+        $nextcloudDir . '/version.php',
69
+        $nextcloudDir . '/lib/private/Share20/ProviderFactory.php',
70
+        $nextcloudDir . '/tests',
71
+        // $nextcloudDir . '/config',
72
+        // $nextcloudDir . '/lib',
73
+        // $nextcloudDir . '/themes',
74
+    ])
75
+    ->withSkip([
76
+        $nextcloudDir . '/apps/*/3rdparty/*',
77
+        $nextcloudDir . '/apps/*/build/stubs/*',
78
+        $nextcloudDir . '/apps/*/composer/*',
79
+        $nextcloudDir . '/apps/*/config/*',
80
+    ])
81
+    // uncomment to reach your current PHP version
82
+    // ->withPhpSets()
83
+    ->withImportNames(importShortClasses:false)
84
+    ->withTypeCoverageLevel(0)
85
+    ->withRules([
86
+        UseSpecificWillMethodRector::class,
87
+        StaticDataProviderClassMethodRector::class,
88
+        DataProviderAnnotationToAttributeRector::class,
89
+    ])
90
+    ->withConfiguredRule(ClassPropertyAssignToConstructorPromotionRector::class, [
91
+        'inline_public' => true,
92
+        'rename_property' => true,
93
+    ])
94
+    ->withSets([
95
+        NextcloudSets::NEXTCLOUD_25,
96
+    ]);
97 97
 
98 98
 $config->registerService(NextcloudNamespaceSkipVoter::class, tag:ClassNameImportSkipVoterInterface::class);
99 99
 
@@ -105,11 +105,11 @@  discard block
 block discarded – undo
105 105
 $ignoredEntries = array_values($ignoredEntries);
106 106
 
107 107
 foreach ($ignoredEntries as $ignoredEntry) {
108
-	if (str_ends_with($ignoredEntry, '/')) {
109
-		$config->withSkip([$ignoredEntry . '*']);
110
-	} else {
111
-		$config->withSkip([$ignoredEntry . '/*']);
112
-	}
108
+    if (str_ends_with($ignoredEntry, '/')) {
109
+        $config->withSkip([$ignoredEntry . '*']);
110
+    } else {
111
+        $config->withSkip([$ignoredEntry . '/*']);
112
+    }
113 113
 }
114 114
 
115 115
 return $config;
Please login to merge, or discard this patch.
core/ajax/update.php 1 patch
Indentation   +104 added lines, -104 removed lines patch added patch discarded remove patch
@@ -31,7 +31,7 @@  discard block
 block discarded – undo
31 31
 use Psr\Log\LoggerInterface;
32 32
 
33 33
 if (!str_contains(@ini_get('disable_functions'), 'set_time_limit')) {
34
-	@set_time_limit(0);
34
+    @set_time_limit(0);
35 35
 }
36 36
 
37 37
 require_once '../../lib/base.php';
@@ -46,117 +46,117 @@  discard block
 block discarded – undo
46 46
 $eventSource->send('success', $l->t('Preparing update'));
47 47
 
48 48
 if (Util::needUpgrade()) {
49
-	$config = Server::get(SystemConfig::class);
50
-	if ($config->getValue('upgrade.disable-web', false)) {
51
-		$eventSource->send('failure', $l->t('Please use the command line updater because updating via browser is disabled in your config.php.'));
52
-		$eventSource->close();
53
-		exit();
54
-	}
49
+    $config = Server::get(SystemConfig::class);
50
+    if ($config->getValue('upgrade.disable-web', false)) {
51
+        $eventSource->send('failure', $l->t('Please use the command line updater because updating via browser is disabled in your config.php.'));
52
+        $eventSource->close();
53
+        exit();
54
+    }
55 55
 
56
-	// if a user is currently logged in, their session must be ignored to
57
-	// avoid side effects
58
-	\OC_User::setIncognitoMode(true);
56
+    // if a user is currently logged in, their session must be ignored to
57
+    // avoid side effects
58
+    \OC_User::setIncognitoMode(true);
59 59
 
60
-	$config = Server::get(IConfig::class);
61
-	$updater = new Updater(
62
-		Server::get(ServerVersion::class),
63
-		$config,
64
-		Server::get(IAppConfig::class),
65
-		Server::get(Checker::class),
66
-		Server::get(LoggerInterface::class),
67
-		Server::get(Installer::class)
68
-	);
69
-	$incompatibleApps = [];
70
-	$incompatibleOverwrites = $config->getSystemValue('app_install_overwrite', []);
60
+    $config = Server::get(IConfig::class);
61
+    $updater = new Updater(
62
+        Server::get(ServerVersion::class),
63
+        $config,
64
+        Server::get(IAppConfig::class),
65
+        Server::get(Checker::class),
66
+        Server::get(LoggerInterface::class),
67
+        Server::get(Installer::class)
68
+    );
69
+    $incompatibleApps = [];
70
+    $incompatibleOverwrites = $config->getSystemValue('app_install_overwrite', []);
71 71
 
72
-	/** @var IEventDispatcher $dispatcher */
73
-	$dispatcher = Server::get(IEventDispatcher::class);
74
-	$dispatcher->addListener(
75
-		MigratorExecuteSqlEvent::class,
76
-		function (MigratorExecuteSqlEvent $event) use ($eventSource, $l): void {
77
-			$eventSource->send('success', $l->t('[%d / %d]: %s', [$event->getCurrentStep(), $event->getMaxStep(), $event->getSql()]));
78
-		}
79
-	);
80
-	$feedBack = new FeedBackHandler($eventSource, $l);
81
-	$dispatcher->addListener(RepairStartEvent::class, [$feedBack, 'handleRepairFeedback']);
82
-	$dispatcher->addListener(RepairAdvanceEvent::class, [$feedBack, 'handleRepairFeedback']);
83
-	$dispatcher->addListener(RepairFinishEvent::class, [$feedBack, 'handleRepairFeedback']);
84
-	$dispatcher->addListener(RepairStepEvent::class, [$feedBack, 'handleRepairFeedback']);
85
-	$dispatcher->addListener(RepairInfoEvent::class, [$feedBack, 'handleRepairFeedback']);
86
-	$dispatcher->addListener(RepairWarningEvent::class, [$feedBack, 'handleRepairFeedback']);
87
-	$dispatcher->addListener(RepairErrorEvent::class, [$feedBack, 'handleRepairFeedback']);
72
+    /** @var IEventDispatcher $dispatcher */
73
+    $dispatcher = Server::get(IEventDispatcher::class);
74
+    $dispatcher->addListener(
75
+        MigratorExecuteSqlEvent::class,
76
+        function (MigratorExecuteSqlEvent $event) use ($eventSource, $l): void {
77
+            $eventSource->send('success', $l->t('[%d / %d]: %s', [$event->getCurrentStep(), $event->getMaxStep(), $event->getSql()]));
78
+        }
79
+    );
80
+    $feedBack = new FeedBackHandler($eventSource, $l);
81
+    $dispatcher->addListener(RepairStartEvent::class, [$feedBack, 'handleRepairFeedback']);
82
+    $dispatcher->addListener(RepairAdvanceEvent::class, [$feedBack, 'handleRepairFeedback']);
83
+    $dispatcher->addListener(RepairFinishEvent::class, [$feedBack, 'handleRepairFeedback']);
84
+    $dispatcher->addListener(RepairStepEvent::class, [$feedBack, 'handleRepairFeedback']);
85
+    $dispatcher->addListener(RepairInfoEvent::class, [$feedBack, 'handleRepairFeedback']);
86
+    $dispatcher->addListener(RepairWarningEvent::class, [$feedBack, 'handleRepairFeedback']);
87
+    $dispatcher->addListener(RepairErrorEvent::class, [$feedBack, 'handleRepairFeedback']);
88 88
 
89
-	$updater->listen('\OC\Updater', 'maintenanceEnabled', function () use ($eventSource, $l): void {
90
-		$eventSource->send('success', $l->t('Turned on maintenance mode'));
91
-	});
92
-	$updater->listen('\OC\Updater', 'maintenanceDisabled', function () use ($eventSource, $l): void {
93
-		$eventSource->send('success', $l->t('Turned off maintenance mode'));
94
-	});
95
-	$updater->listen('\OC\Updater', 'maintenanceActive', function () use ($eventSource, $l): void {
96
-		$eventSource->send('success', $l->t('Maintenance mode is kept active'));
97
-	});
98
-	$updater->listen('\OC\Updater', 'dbUpgradeBefore', function () use ($eventSource, $l): void {
99
-		$eventSource->send('success', $l->t('Updating database schema'));
100
-	});
101
-	$updater->listen('\OC\Updater', 'dbUpgrade', function () use ($eventSource, $l): void {
102
-		$eventSource->send('success', $l->t('Updated database'));
103
-	});
104
-	$updater->listen('\OC\Updater', 'upgradeAppStoreApp', function ($app) use ($eventSource, $l): void {
105
-		$eventSource->send('success', $l->t('Update app "%s" from App Store', [$app]));
106
-	});
107
-	$updater->listen('\OC\Updater', 'appSimulateUpdate', function ($app) use ($eventSource, $l): void {
108
-		$eventSource->send('success', $l->t('Checking whether the database schema for %s can be updated (this can take a long time depending on the database size)', [$app]));
109
-	});
110
-	$updater->listen('\OC\Updater', 'appUpgrade', function ($app, $version) use ($eventSource, $l): void {
111
-		$eventSource->send('success', $l->t('Updated "%1$s" to %2$s', [$app, $version]));
112
-	});
113
-	$updater->listen('\OC\Updater', 'incompatibleAppDisabled', function ($app) use (&$incompatibleApps, &$incompatibleOverwrites): void {
114
-		if (!in_array($app, $incompatibleOverwrites)) {
115
-			$incompatibleApps[] = $app;
116
-		}
117
-	});
118
-	$updater->listen('\OC\Updater', 'failure', function ($message) use ($eventSource, $config): void {
119
-		$eventSource->send('failure', $message);
120
-		$eventSource->close();
121
-		$config->setSystemValue('maintenance', false);
122
-	});
123
-	$updater->listen('\OC\Updater', 'setDebugLogLevel', function ($logLevel, $logLevelName) use ($eventSource, $l): void {
124
-		$eventSource->send('success', $l->t('Set log level to debug'));
125
-	});
126
-	$updater->listen('\OC\Updater', 'resetLogLevel', function ($logLevel, $logLevelName) use ($eventSource, $l): void {
127
-		$eventSource->send('success', $l->t('Reset log level'));
128
-	});
129
-	$updater->listen('\OC\Updater', 'startCheckCodeIntegrity', function () use ($eventSource, $l): void {
130
-		$eventSource->send('success', $l->t('Starting code integrity check'));
131
-	});
132
-	$updater->listen('\OC\Updater', 'finishedCheckCodeIntegrity', function () use ($eventSource, $l): void {
133
-		$eventSource->send('success', $l->t('Finished code integrity check'));
134
-	});
89
+    $updater->listen('\OC\Updater', 'maintenanceEnabled', function () use ($eventSource, $l): void {
90
+        $eventSource->send('success', $l->t('Turned on maintenance mode'));
91
+    });
92
+    $updater->listen('\OC\Updater', 'maintenanceDisabled', function () use ($eventSource, $l): void {
93
+        $eventSource->send('success', $l->t('Turned off maintenance mode'));
94
+    });
95
+    $updater->listen('\OC\Updater', 'maintenanceActive', function () use ($eventSource, $l): void {
96
+        $eventSource->send('success', $l->t('Maintenance mode is kept active'));
97
+    });
98
+    $updater->listen('\OC\Updater', 'dbUpgradeBefore', function () use ($eventSource, $l): void {
99
+        $eventSource->send('success', $l->t('Updating database schema'));
100
+    });
101
+    $updater->listen('\OC\Updater', 'dbUpgrade', function () use ($eventSource, $l): void {
102
+        $eventSource->send('success', $l->t('Updated database'));
103
+    });
104
+    $updater->listen('\OC\Updater', 'upgradeAppStoreApp', function ($app) use ($eventSource, $l): void {
105
+        $eventSource->send('success', $l->t('Update app "%s" from App Store', [$app]));
106
+    });
107
+    $updater->listen('\OC\Updater', 'appSimulateUpdate', function ($app) use ($eventSource, $l): void {
108
+        $eventSource->send('success', $l->t('Checking whether the database schema for %s can be updated (this can take a long time depending on the database size)', [$app]));
109
+    });
110
+    $updater->listen('\OC\Updater', 'appUpgrade', function ($app, $version) use ($eventSource, $l): void {
111
+        $eventSource->send('success', $l->t('Updated "%1$s" to %2$s', [$app, $version]));
112
+    });
113
+    $updater->listen('\OC\Updater', 'incompatibleAppDisabled', function ($app) use (&$incompatibleApps, &$incompatibleOverwrites): void {
114
+        if (!in_array($app, $incompatibleOverwrites)) {
115
+            $incompatibleApps[] = $app;
116
+        }
117
+    });
118
+    $updater->listen('\OC\Updater', 'failure', function ($message) use ($eventSource, $config): void {
119
+        $eventSource->send('failure', $message);
120
+        $eventSource->close();
121
+        $config->setSystemValue('maintenance', false);
122
+    });
123
+    $updater->listen('\OC\Updater', 'setDebugLogLevel', function ($logLevel, $logLevelName) use ($eventSource, $l): void {
124
+        $eventSource->send('success', $l->t('Set log level to debug'));
125
+    });
126
+    $updater->listen('\OC\Updater', 'resetLogLevel', function ($logLevel, $logLevelName) use ($eventSource, $l): void {
127
+        $eventSource->send('success', $l->t('Reset log level'));
128
+    });
129
+    $updater->listen('\OC\Updater', 'startCheckCodeIntegrity', function () use ($eventSource, $l): void {
130
+        $eventSource->send('success', $l->t('Starting code integrity check'));
131
+    });
132
+    $updater->listen('\OC\Updater', 'finishedCheckCodeIntegrity', function () use ($eventSource, $l): void {
133
+        $eventSource->send('success', $l->t('Finished code integrity check'));
134
+    });
135 135
 
136
-	try {
137
-		$updater->upgrade();
138
-	} catch (\Exception $e) {
139
-		Server::get(LoggerInterface::class)->error(
140
-			$e->getMessage(),
141
-			[
142
-				'exception' => $e,
143
-				'app' => 'update',
144
-			]);
145
-		$eventSource->send('failure', get_class($e) . ': ' . $e->getMessage());
146
-		$eventSource->close();
147
-		exit();
148
-	}
136
+    try {
137
+        $updater->upgrade();
138
+    } catch (\Exception $e) {
139
+        Server::get(LoggerInterface::class)->error(
140
+            $e->getMessage(),
141
+            [
142
+                'exception' => $e,
143
+                'app' => 'update',
144
+            ]);
145
+        $eventSource->send('failure', get_class($e) . ': ' . $e->getMessage());
146
+        $eventSource->close();
147
+        exit();
148
+    }
149 149
 
150
-	$disabledApps = [];
151
-	foreach ($incompatibleApps as $app) {
152
-		$disabledApps[$app] = $l->t('%s (incompatible)', [$app]);
153
-	}
150
+    $disabledApps = [];
151
+    foreach ($incompatibleApps as $app) {
152
+        $disabledApps[$app] = $l->t('%s (incompatible)', [$app]);
153
+    }
154 154
 
155
-	if (!empty($disabledApps)) {
156
-		$eventSource->send('notice', $l->t('The following apps have been disabled: %s', [implode(', ', $disabledApps)]));
157
-	}
155
+    if (!empty($disabledApps)) {
156
+        $eventSource->send('notice', $l->t('The following apps have been disabled: %s', [implode(', ', $disabledApps)]));
157
+    }
158 158
 } else {
159
-	$eventSource->send('notice', $l->t('Already up to date'));
159
+    $eventSource->send('notice', $l->t('Already up to date'));
160 160
 }
161 161
 
162 162
 $eventSource->send('done', '');
Please login to merge, or discard this patch.
apps/settings/tests/UserMigration/AccountMigratorTest.php 1 patch
Indentation   +135 added lines, -135 removed lines patch added patch discarded remove patch
@@ -27,139 +27,139 @@
 block discarded – undo
27 27
  * @group DB
28 28
  */
29 29
 class AccountMigratorTest extends TestCase {
30
-	private IUserManager $userManager;
31
-	private IAvatarManager $avatarManager;
32
-	private AccountMigrator $migrator;
33
-	private IImportSource&MockObject $importSource;
34
-	private IExportDestination&MockObject $exportDestination;
35
-	private OutputInterface&MockObject $output;
36
-
37
-	private const ASSETS_DIR = __DIR__ . '/assets/';
38
-
39
-	private const REGEX_ACCOUNT_FILE = '/^' . Application::APP_ID . '\/' . '[a-z]+\.json' . '$/';
40
-
41
-	private const REGEX_AVATAR_FILE = '/^' . Application::APP_ID . '\/' . 'avatar\.(jpg|png)' . '$/';
42
-
43
-	private const REGEX_CONFIG_FILE = '/^' . Application::APP_ID . '\/' . '[a-z]+\.json' . '$/';
44
-
45
-	protected function setUp(): void {
46
-		parent::setUp();
47
-
48
-		$app = new App(Application::APP_ID);
49
-		$container = $app->getContainer();
50
-		$container->get(IConfig::class)->setSystemValue('has_internet_connection', false);
51
-
52
-		$this->userManager = $container->get(IUserManager::class);
53
-		$this->avatarManager = $container->get(IAvatarManager::class);
54
-		$this->migrator = $container->get(AccountMigrator::class);
55
-
56
-		$this->importSource = $this->createMock(IImportSource::class);
57
-		$this->exportDestination = $this->createMock(IExportDestination::class);
58
-		$this->output = $this->createMock(OutputInterface::class);
59
-	}
60
-
61
-	protected function tearDown(): void {
62
-		Server::get(IConfig::class)->setSystemValue('has_internet_connection', true);
63
-		parent::tearDown();
64
-	}
65
-
66
-	public static function dataImportExportAccount(): array {
67
-		return array_map(
68
-			static function (string $filename): array {
69
-				$dataPath = static::ASSETS_DIR . $filename;
70
-				// For each account json file there is an avatar image and a config json file with the same basename
71
-				$basename = pathinfo($filename, PATHINFO_FILENAME);
72
-				$avatarPath = static::ASSETS_DIR . (file_exists(static::ASSETS_DIR . "$basename.jpg") ? "$basename.jpg" : "$basename.png");
73
-				$configPath = static::ASSETS_DIR . "$basename-config." . pathinfo($filename, PATHINFO_EXTENSION);
74
-				return [
75
-					UUIDUtil::getUUID(),
76
-					json_decode(file_get_contents($dataPath), true, 512, JSON_THROW_ON_ERROR),
77
-					$avatarPath,
78
-					json_decode(file_get_contents($configPath), true, 512, JSON_THROW_ON_ERROR),
79
-				];
80
-			},
81
-			array_filter(
82
-				scandir(static::ASSETS_DIR),
83
-				fn (string $filename) => pathinfo($filename, PATHINFO_EXTENSION) === 'json' && mb_strpos(pathinfo($filename, PATHINFO_FILENAME), 'config') === false,
84
-			),
85
-		);
86
-	}
87
-
88
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataImportExportAccount')]
89
-	public function testImportExportAccount(string $userId, array $importData, string $avatarPath, array $importConfig): void {
90
-		$user = $this->userManager->createUser($userId, 'topsecretpassword');
91
-		$avatarExt = pathinfo($avatarPath, PATHINFO_EXTENSION);
92
-		$exportData = $importData;
93
-		$exportConfig = $importConfig;
94
-		// Verification status of email will be set to in progress on import so we set the export data to reflect that
95
-		$exportData[IAccountManager::PROPERTY_EMAIL]['verified'] = IAccountManager::VERIFICATION_IN_PROGRESS;
96
-
97
-		$this->importSource
98
-			->expects($this->once())
99
-			->method('getMigratorVersion')
100
-			->with($this->migrator->getId())
101
-			->willReturn(1);
102
-
103
-		$calls = [
104
-			[static::REGEX_ACCOUNT_FILE, json_encode($importData)],
105
-			[static::REGEX_CONFIG_FILE, json_encode($importConfig)],
106
-		];
107
-		$this->importSource
108
-			->expects($this->exactly(2))
109
-			->method('getFileContents')
110
-			->willReturnCallback(function ($path) use (&$calls) {
111
-				$expected = array_shift($calls);
112
-				$this->assertMatchesRegularExpression($expected[0], $path);
113
-				return $expected[1];
114
-			});
115
-
116
-		$this->importSource
117
-			->expects($this->once())
118
-			->method('getFolderListing')
119
-			->with(Application::APP_ID . '/')
120
-			->willReturn(["avatar.$avatarExt"]);
121
-
122
-		$this->importSource
123
-			->expects($this->once())
124
-			->method('getFileAsStream')
125
-			->with($this->matchesRegularExpression(static::REGEX_AVATAR_FILE))
126
-			->willReturn(fopen($avatarPath, 'r'));
127
-
128
-		$this->migrator->import($user, $this->importSource, $this->output);
129
-
130
-		$importedAvatar = $this->avatarManager->getAvatar($user->getUID());
131
-		$this->assertTrue($importedAvatar->isCustomAvatar());
132
-
133
-		/**
134
-		 * Avatar images are re-encoded on import therefore JPEG images which use lossy compression cannot be checked for equality
135
-		 * @see https://github.com/nextcloud/server/blob/9644b7e505dc90a1e683f77ad38dc6dc4e90fa2f/lib/private/legacy/OC_Image.php#L383-L390
136
-		 */
137
-
138
-		if ($avatarExt !== 'jpg') {
139
-			$this->assertStringEqualsFile(
140
-				$avatarPath,
141
-				$importedAvatar->getFile(-1)->getContent(),
142
-			);
143
-		}
144
-
145
-		$calls = [
146
-			[static::REGEX_ACCOUNT_FILE, new JsonMatches(json_encode($importData))],
147
-			[static::REGEX_CONFIG_FILE,new JsonMatches(json_encode($importConfig))],
148
-		];
149
-		$this->exportDestination
150
-			->expects($this->exactly(2))
151
-			->method('addFileContents')
152
-			->willReturnCallback(function ($path) use (&$calls) {
153
-				$expected = array_shift($calls);
154
-				$this->assertMatchesRegularExpression($expected[0], $path);
155
-				return $expected[1];
156
-			});
157
-
158
-		$this->exportDestination
159
-			->expects($this->once())
160
-			->method('addFileAsStream')
161
-			->with($this->matchesRegularExpression(static::REGEX_AVATAR_FILE), $this->isType('resource'));
162
-
163
-		$this->migrator->export($user, $this->exportDestination, $this->output);
164
-	}
30
+    private IUserManager $userManager;
31
+    private IAvatarManager $avatarManager;
32
+    private AccountMigrator $migrator;
33
+    private IImportSource&MockObject $importSource;
34
+    private IExportDestination&MockObject $exportDestination;
35
+    private OutputInterface&MockObject $output;
36
+
37
+    private const ASSETS_DIR = __DIR__ . '/assets/';
38
+
39
+    private const REGEX_ACCOUNT_FILE = '/^' . Application::APP_ID . '\/' . '[a-z]+\.json' . '$/';
40
+
41
+    private const REGEX_AVATAR_FILE = '/^' . Application::APP_ID . '\/' . 'avatar\.(jpg|png)' . '$/';
42
+
43
+    private const REGEX_CONFIG_FILE = '/^' . Application::APP_ID . '\/' . '[a-z]+\.json' . '$/';
44
+
45
+    protected function setUp(): void {
46
+        parent::setUp();
47
+
48
+        $app = new App(Application::APP_ID);
49
+        $container = $app->getContainer();
50
+        $container->get(IConfig::class)->setSystemValue('has_internet_connection', false);
51
+
52
+        $this->userManager = $container->get(IUserManager::class);
53
+        $this->avatarManager = $container->get(IAvatarManager::class);
54
+        $this->migrator = $container->get(AccountMigrator::class);
55
+
56
+        $this->importSource = $this->createMock(IImportSource::class);
57
+        $this->exportDestination = $this->createMock(IExportDestination::class);
58
+        $this->output = $this->createMock(OutputInterface::class);
59
+    }
60
+
61
+    protected function tearDown(): void {
62
+        Server::get(IConfig::class)->setSystemValue('has_internet_connection', true);
63
+        parent::tearDown();
64
+    }
65
+
66
+    public static function dataImportExportAccount(): array {
67
+        return array_map(
68
+            static function (string $filename): array {
69
+                $dataPath = static::ASSETS_DIR . $filename;
70
+                // For each account json file there is an avatar image and a config json file with the same basename
71
+                $basename = pathinfo($filename, PATHINFO_FILENAME);
72
+                $avatarPath = static::ASSETS_DIR . (file_exists(static::ASSETS_DIR . "$basename.jpg") ? "$basename.jpg" : "$basename.png");
73
+                $configPath = static::ASSETS_DIR . "$basename-config." . pathinfo($filename, PATHINFO_EXTENSION);
74
+                return [
75
+                    UUIDUtil::getUUID(),
76
+                    json_decode(file_get_contents($dataPath), true, 512, JSON_THROW_ON_ERROR),
77
+                    $avatarPath,
78
+                    json_decode(file_get_contents($configPath), true, 512, JSON_THROW_ON_ERROR),
79
+                ];
80
+            },
81
+            array_filter(
82
+                scandir(static::ASSETS_DIR),
83
+                fn (string $filename) => pathinfo($filename, PATHINFO_EXTENSION) === 'json' && mb_strpos(pathinfo($filename, PATHINFO_FILENAME), 'config') === false,
84
+            ),
85
+        );
86
+    }
87
+
88
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataImportExportAccount')]
89
+    public function testImportExportAccount(string $userId, array $importData, string $avatarPath, array $importConfig): void {
90
+        $user = $this->userManager->createUser($userId, 'topsecretpassword');
91
+        $avatarExt = pathinfo($avatarPath, PATHINFO_EXTENSION);
92
+        $exportData = $importData;
93
+        $exportConfig = $importConfig;
94
+        // Verification status of email will be set to in progress on import so we set the export data to reflect that
95
+        $exportData[IAccountManager::PROPERTY_EMAIL]['verified'] = IAccountManager::VERIFICATION_IN_PROGRESS;
96
+
97
+        $this->importSource
98
+            ->expects($this->once())
99
+            ->method('getMigratorVersion')
100
+            ->with($this->migrator->getId())
101
+            ->willReturn(1);
102
+
103
+        $calls = [
104
+            [static::REGEX_ACCOUNT_FILE, json_encode($importData)],
105
+            [static::REGEX_CONFIG_FILE, json_encode($importConfig)],
106
+        ];
107
+        $this->importSource
108
+            ->expects($this->exactly(2))
109
+            ->method('getFileContents')
110
+            ->willReturnCallback(function ($path) use (&$calls) {
111
+                $expected = array_shift($calls);
112
+                $this->assertMatchesRegularExpression($expected[0], $path);
113
+                return $expected[1];
114
+            });
115
+
116
+        $this->importSource
117
+            ->expects($this->once())
118
+            ->method('getFolderListing')
119
+            ->with(Application::APP_ID . '/')
120
+            ->willReturn(["avatar.$avatarExt"]);
121
+
122
+        $this->importSource
123
+            ->expects($this->once())
124
+            ->method('getFileAsStream')
125
+            ->with($this->matchesRegularExpression(static::REGEX_AVATAR_FILE))
126
+            ->willReturn(fopen($avatarPath, 'r'));
127
+
128
+        $this->migrator->import($user, $this->importSource, $this->output);
129
+
130
+        $importedAvatar = $this->avatarManager->getAvatar($user->getUID());
131
+        $this->assertTrue($importedAvatar->isCustomAvatar());
132
+
133
+        /**
134
+         * Avatar images are re-encoded on import therefore JPEG images which use lossy compression cannot be checked for equality
135
+         * @see https://github.com/nextcloud/server/blob/9644b7e505dc90a1e683f77ad38dc6dc4e90fa2f/lib/private/legacy/OC_Image.php#L383-L390
136
+         */
137
+
138
+        if ($avatarExt !== 'jpg') {
139
+            $this->assertStringEqualsFile(
140
+                $avatarPath,
141
+                $importedAvatar->getFile(-1)->getContent(),
142
+            );
143
+        }
144
+
145
+        $calls = [
146
+            [static::REGEX_ACCOUNT_FILE, new JsonMatches(json_encode($importData))],
147
+            [static::REGEX_CONFIG_FILE,new JsonMatches(json_encode($importConfig))],
148
+        ];
149
+        $this->exportDestination
150
+            ->expects($this->exactly(2))
151
+            ->method('addFileContents')
152
+            ->willReturnCallback(function ($path) use (&$calls) {
153
+                $expected = array_shift($calls);
154
+                $this->assertMatchesRegularExpression($expected[0], $path);
155
+                return $expected[1];
156
+            });
157
+
158
+        $this->exportDestination
159
+            ->expects($this->once())
160
+            ->method('addFileAsStream')
161
+            ->with($this->matchesRegularExpression(static::REGEX_AVATAR_FILE), $this->isType('resource'));
162
+
163
+        $this->migrator->export($user, $this->exportDestination, $this->output);
164
+    }
165 165
 }
Please login to merge, or discard this patch.
apps/settings/tests/AppInfo/ApplicationTest.php 1 patch
Indentation   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -28,36 +28,36 @@
 block discarded – undo
28 28
  * @group DB
29 29
  */
30 30
 class ApplicationTest extends TestCase {
31
-	protected Application $app;
32
-	protected IAppContainer $container;
33
-
34
-	protected function setUp(): void {
35
-		parent::setUp();
36
-		$this->app = new Application();
37
-		$this->container = $this->app->getContainer();
38
-	}
39
-
40
-	public function testContainerAppName(): void {
41
-		$this->app = new Application();
42
-		$this->assertEquals('settings', $this->container->getAppName());
43
-	}
44
-
45
-	public static function dataContainerQuery(): array {
46
-		return [
47
-			[AdminSettingsController::class, Controller::class],
48
-			[AppSettingsController::class, Controller::class],
49
-			[AuthSettingsController::class, Controller::class],
50
-			[CheckSetupController::class, Controller::class],
51
-			[LogSettingsController::class, Controller::class],
52
-			[MailSettingsController::class, Controller::class],
53
-			[UsersController::class, Controller::class],
54
-
55
-			[SubadminMiddleware::class, Middleware::class],
56
-		];
57
-	}
58
-
59
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataContainerQuery')]
60
-	public function testContainerQuery(string $service, string $expected): void {
61
-		$this->assertTrue($this->container->query($service) instanceof $expected);
62
-	}
31
+    protected Application $app;
32
+    protected IAppContainer $container;
33
+
34
+    protected function setUp(): void {
35
+        parent::setUp();
36
+        $this->app = new Application();
37
+        $this->container = $this->app->getContainer();
38
+    }
39
+
40
+    public function testContainerAppName(): void {
41
+        $this->app = new Application();
42
+        $this->assertEquals('settings', $this->container->getAppName());
43
+    }
44
+
45
+    public static function dataContainerQuery(): array {
46
+        return [
47
+            [AdminSettingsController::class, Controller::class],
48
+            [AppSettingsController::class, Controller::class],
49
+            [AuthSettingsController::class, Controller::class],
50
+            [CheckSetupController::class, Controller::class],
51
+            [LogSettingsController::class, Controller::class],
52
+            [MailSettingsController::class, Controller::class],
53
+            [UsersController::class, Controller::class],
54
+
55
+            [SubadminMiddleware::class, Middleware::class],
56
+        ];
57
+    }
58
+
59
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataContainerQuery')]
60
+    public function testContainerQuery(string $service, string $expected): void {
61
+        $this->assertTrue($this->container->query($service) instanceof $expected);
62
+    }
63 63
 }
Please login to merge, or discard this patch.
apps/settings/tests/SetupChecks/ForwardedForHeadersTest.php 1 patch
Indentation   +90 added lines, -90 removed lines patch added patch discarded remove patch
@@ -17,103 +17,103 @@
 block discarded – undo
17 17
 use Test\TestCase;
18 18
 
19 19
 class ForwardedForHeadersTest extends TestCase {
20
-	private IL10N $l10n;
21
-	private IConfig $config;
22
-	private IURLGenerator $urlGenerator;
23
-	private IRequest $request;
24
-	private ForwardedForHeaders $check;
20
+    private IL10N $l10n;
21
+    private IConfig $config;
22
+    private IURLGenerator $urlGenerator;
23
+    private IRequest $request;
24
+    private ForwardedForHeaders $check;
25 25
 
26
-	protected function setUp(): void {
27
-		parent::setUp();
26
+    protected function setUp(): void {
27
+        parent::setUp();
28 28
 
29
-		$this->l10n = $this->createMock(IL10N::class);
30
-		$this->l10n->expects($this->any())
31
-			->method('t')
32
-			->willReturnCallback(function ($message, array $replace) {
33
-				return vsprintf($message, $replace);
34
-			});
35
-		$this->config = $this->getMockBuilder(IConfig::class)->getMock();
36
-		$this->urlGenerator = $this->getMockBuilder(IURLGenerator::class)->getMock();
37
-		$this->request = $this->getMockBuilder(IRequest::class)->getMock();
38
-		$this->check = new ForwardedForHeaders(
39
-			$this->l10n,
40
-			$this->config,
41
-			$this->urlGenerator,
42
-			$this->request,
43
-		);
44
-	}
29
+        $this->l10n = $this->createMock(IL10N::class);
30
+        $this->l10n->expects($this->any())
31
+            ->method('t')
32
+            ->willReturnCallback(function ($message, array $replace) {
33
+                return vsprintf($message, $replace);
34
+            });
35
+        $this->config = $this->getMockBuilder(IConfig::class)->getMock();
36
+        $this->urlGenerator = $this->getMockBuilder(IURLGenerator::class)->getMock();
37
+        $this->request = $this->getMockBuilder(IRequest::class)->getMock();
38
+        $this->check = new ForwardedForHeaders(
39
+            $this->l10n,
40
+            $this->config,
41
+            $this->urlGenerator,
42
+            $this->request,
43
+        );
44
+    }
45 45
 
46
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataForwardedForHeadersWorking')]
47
-	public function testForwardedForHeadersWorking(array $trustedProxies, string $remoteAddrNotForwarded, string $remoteAddr, string $result): void {
48
-		$this->config->expects($this->once())
49
-			->method('getSystemValue')
50
-			->with('trusted_proxies', [])
51
-			->willReturn($trustedProxies);
52
-		$this->request->expects($this->atLeastOnce())
53
-			->method('getHeader')
54
-			->willReturnMap([
55
-				['REMOTE_ADDR', $remoteAddrNotForwarded],
56
-				['X-Forwarded-Host', '']
57
-			]);
58
-		$this->request->expects($this->any())
59
-			->method('getRemoteAddress')
60
-			->willReturn($remoteAddr);
46
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataForwardedForHeadersWorking')]
47
+    public function testForwardedForHeadersWorking(array $trustedProxies, string $remoteAddrNotForwarded, string $remoteAddr, string $result): void {
48
+        $this->config->expects($this->once())
49
+            ->method('getSystemValue')
50
+            ->with('trusted_proxies', [])
51
+            ->willReturn($trustedProxies);
52
+        $this->request->expects($this->atLeastOnce())
53
+            ->method('getHeader')
54
+            ->willReturnMap([
55
+                ['REMOTE_ADDR', $remoteAddrNotForwarded],
56
+                ['X-Forwarded-Host', '']
57
+            ]);
58
+        $this->request->expects($this->any())
59
+            ->method('getRemoteAddress')
60
+            ->willReturn($remoteAddr);
61 61
 
62
-		$this->assertEquals(
63
-			$result,
64
-			$this->check->run()->getSeverity()
65
-		);
66
-	}
62
+        $this->assertEquals(
63
+            $result,
64
+            $this->check->run()->getSeverity()
65
+        );
66
+    }
67 67
 
68
-	public static function dataForwardedForHeadersWorking(): array {
69
-		return [
70
-			// description => trusted proxies, getHeader('REMOTE_ADDR'), getRemoteAddr, expected result
71
-			'no trusted proxies' => [[], '2.2.2.2', '2.2.2.2', SetupResult::SUCCESS],
72
-			'trusted proxy, remote addr not trusted proxy' => [['1.1.1.1'], '2.2.2.2', '2.2.2.2', SetupResult::SUCCESS],
73
-			'trusted proxy, remote addr is trusted proxy, x-forwarded-for working' => [['1.1.1.1'], '1.1.1.1', '2.2.2.2', SetupResult::SUCCESS],
74
-			'trusted proxy, remote addr is trusted proxy, x-forwarded-for not set' => [['1.1.1.1'], '1.1.1.1', '1.1.1.1', SetupResult::WARNING],
75
-		];
76
-	}
68
+    public static function dataForwardedForHeadersWorking(): array {
69
+        return [
70
+            // description => trusted proxies, getHeader('REMOTE_ADDR'), getRemoteAddr, expected result
71
+            'no trusted proxies' => [[], '2.2.2.2', '2.2.2.2', SetupResult::SUCCESS],
72
+            'trusted proxy, remote addr not trusted proxy' => [['1.1.1.1'], '2.2.2.2', '2.2.2.2', SetupResult::SUCCESS],
73
+            'trusted proxy, remote addr is trusted proxy, x-forwarded-for working' => [['1.1.1.1'], '1.1.1.1', '2.2.2.2', SetupResult::SUCCESS],
74
+            'trusted proxy, remote addr is trusted proxy, x-forwarded-for not set' => [['1.1.1.1'], '1.1.1.1', '1.1.1.1', SetupResult::WARNING],
75
+        ];
76
+    }
77 77
 
78
-	public function testForwardedHostPresentButTrustedProxiesNotAnArray(): void {
79
-		$this->config->expects($this->once())
80
-			->method('getSystemValue')
81
-			->with('trusted_proxies', [])
82
-			->willReturn('1.1.1.1');
83
-		$this->request->expects($this->atLeastOnce())
84
-			->method('getHeader')
85
-			->willReturnMap([
86
-				['REMOTE_ADDR', '1.1.1.1'],
87
-				['X-Forwarded-Host', 'nextcloud.test']
88
-			]);
89
-		$this->request->expects($this->any())
90
-			->method('getRemoteAddress')
91
-			->willReturn('1.1.1.1');
78
+    public function testForwardedHostPresentButTrustedProxiesNotAnArray(): void {
79
+        $this->config->expects($this->once())
80
+            ->method('getSystemValue')
81
+            ->with('trusted_proxies', [])
82
+            ->willReturn('1.1.1.1');
83
+        $this->request->expects($this->atLeastOnce())
84
+            ->method('getHeader')
85
+            ->willReturnMap([
86
+                ['REMOTE_ADDR', '1.1.1.1'],
87
+                ['X-Forwarded-Host', 'nextcloud.test']
88
+            ]);
89
+        $this->request->expects($this->any())
90
+            ->method('getRemoteAddress')
91
+            ->willReturn('1.1.1.1');
92 92
 
93
-		$this->assertEquals(
94
-			SetupResult::ERROR,
95
-			$this->check->run()->getSeverity()
96
-		);
97
-	}
93
+        $this->assertEquals(
94
+            SetupResult::ERROR,
95
+            $this->check->run()->getSeverity()
96
+        );
97
+    }
98 98
 
99
-	public function testForwardedHostPresentButTrustedProxiesEmpty(): void {
100
-		$this->config->expects($this->once())
101
-			->method('getSystemValue')
102
-			->with('trusted_proxies', [])
103
-			->willReturn([]);
104
-		$this->request->expects($this->atLeastOnce())
105
-			->method('getHeader')
106
-			->willReturnMap([
107
-				['REMOTE_ADDR', '1.1.1.1'],
108
-				['X-Forwarded-Host', 'nextcloud.test']
109
-			]);
110
-		$this->request->expects($this->any())
111
-			->method('getRemoteAddress')
112
-			->willReturn('1.1.1.1');
99
+    public function testForwardedHostPresentButTrustedProxiesEmpty(): void {
100
+        $this->config->expects($this->once())
101
+            ->method('getSystemValue')
102
+            ->with('trusted_proxies', [])
103
+            ->willReturn([]);
104
+        $this->request->expects($this->atLeastOnce())
105
+            ->method('getHeader')
106
+            ->willReturnMap([
107
+                ['REMOTE_ADDR', '1.1.1.1'],
108
+                ['X-Forwarded-Host', 'nextcloud.test']
109
+            ]);
110
+        $this->request->expects($this->any())
111
+            ->method('getRemoteAddress')
112
+            ->willReturn('1.1.1.1');
113 113
 
114
-		$this->assertEquals(
115
-			SetupResult::ERROR,
116
-			$this->check->run()->getSeverity()
117
-		);
118
-	}
114
+        $this->assertEquals(
115
+            SetupResult::ERROR,
116
+            $this->check->run()->getSeverity()
117
+        );
118
+    }
119 119
 }
Please login to merge, or discard this patch.
apps/settings/tests/SetupChecks/LoggingLevelTest.php 2 patches
Indentation   +45 added lines, -45 removed lines patch added patch discarded remove patch
@@ -19,58 +19,58 @@
 block discarded – undo
19 19
 use Test\TestCase;
20 20
 
21 21
 class LoggingLevelTest extends TestCase {
22
-	private IL10N&MockObject $l10n;
23
-	private IConfig&MockObject $config;
24
-	private IURLGenerator&MockObject $urlGenerator;
22
+    private IL10N&MockObject $l10n;
23
+    private IConfig&MockObject $config;
24
+    private IURLGenerator&MockObject $urlGenerator;
25 25
 
26
-	protected function setUp(): void {
27
-		parent::setUp();
26
+    protected function setUp(): void {
27
+        parent::setUp();
28 28
 
29
-		$this->l10n = $this->createMock(IL10N::class);
30
-		$this->l10n->expects($this->any())
31
-			->method('t')
32
-			->willReturnCallback(function ($message, array $replace) {
33
-				return vsprintf($message, $replace);
34
-			});
35
-		$this->config = $this->createMock(IConfig::class);
36
-		$this->urlGenerator = $this->createMock(IURLGenerator::class);
37
-	}
29
+        $this->l10n = $this->createMock(IL10N::class);
30
+        $this->l10n->expects($this->any())
31
+            ->method('t')
32
+            ->willReturnCallback(function ($message, array $replace) {
33
+                return vsprintf($message, $replace);
34
+            });
35
+        $this->config = $this->createMock(IConfig::class);
36
+        $this->urlGenerator = $this->createMock(IURLGenerator::class);
37
+    }
38 38
 
39
-	public static function dataRun(): array {
40
-		return [
41
-			[ILogger::INFO, SetupResult::SUCCESS],
42
-			[ILogger::WARN, SetupResult::SUCCESS],
43
-			[ILogger::ERROR, SetupResult::SUCCESS],
44
-			[ILogger::FATAL, SetupResult::SUCCESS],
39
+    public static function dataRun(): array {
40
+        return [
41
+            [ILogger::INFO, SetupResult::SUCCESS],
42
+            [ILogger::WARN, SetupResult::SUCCESS],
43
+            [ILogger::ERROR, SetupResult::SUCCESS],
44
+            [ILogger::FATAL, SetupResult::SUCCESS],
45 45
 
46
-			// Debug is valid but will result in an warning
47
-			[ILogger::DEBUG, SetupResult::WARNING],
46
+            // Debug is valid but will result in an warning
47
+            [ILogger::DEBUG, SetupResult::WARNING],
48 48
 
49
-			// negative - invalid range
50
-			[-1, SetupResult::ERROR],
51
-			// string value instead of number
52
-			['1', SetupResult::ERROR],
53
-			// random string value
54
-			['error', SetupResult::ERROR],
55
-			// PSR logger value
56
-			[LogLevel::ALERT, SetupResult::ERROR],
57
-			// out of range
58
-			[ILogger::FATAL + 1, SetupResult::ERROR],
59
-		];
60
-	}
49
+            // negative - invalid range
50
+            [-1, SetupResult::ERROR],
51
+            // string value instead of number
52
+            ['1', SetupResult::ERROR],
53
+            // random string value
54
+            ['error', SetupResult::ERROR],
55
+            // PSR logger value
56
+            [LogLevel::ALERT, SetupResult::ERROR],
57
+            // out of range
58
+            [ILogger::FATAL + 1, SetupResult::ERROR],
59
+        ];
60
+    }
61 61
 
62
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataRun')]
63
-	public function testRun(string|int $value, string $expected): void {
64
-		$this->urlGenerator->method('linkToDocs')->willReturn('admin-logging');
62
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataRun')]
63
+    public function testRun(string|int $value, string $expected): void {
64
+        $this->urlGenerator->method('linkToDocs')->willReturn('admin-logging');
65 65
 
66
-		$this->config->expects(self::once())
67
-			->method('getSystemValue')
68
-			->with('loglevel', ILogger::WARN)
69
-			->willReturn($value);
66
+        $this->config->expects(self::once())
67
+            ->method('getSystemValue')
68
+            ->with('loglevel', ILogger::WARN)
69
+            ->willReturn($value);
70 70
 
71
-		$check = new LoggingLevel($this->l10n, $this->config, $this->urlGenerator);
71
+        $check = new LoggingLevel($this->l10n, $this->config, $this->urlGenerator);
72 72
 
73
-		$result = $check->run();
74
-		$this->assertEquals($expected, $result->getSeverity());
75
-	}
73
+        $result = $check->run();
74
+        $this->assertEquals($expected, $result->getSeverity());
75
+    }
76 76
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -29,7 +29,7 @@  discard block
 block discarded – undo
29 29
 		$this->l10n = $this->createMock(IL10N::class);
30 30
 		$this->l10n->expects($this->any())
31 31
 			->method('t')
32
-			->willReturnCallback(function ($message, array $replace) {
32
+			->willReturnCallback(function($message, array $replace) {
33 33
 				return vsprintf($message, $replace);
34 34
 			});
35 35
 		$this->config = $this->createMock(IConfig::class);
@@ -60,7 +60,7 @@  discard block
 block discarded – undo
60 60
 	}
61 61
 
62 62
 	#[\PHPUnit\Framework\Attributes\DataProvider('dataRun')]
63
-	public function testRun(string|int $value, string $expected): void {
63
+	public function testRun(string | int $value, string $expected): void {
64 64
 		$this->urlGenerator->method('linkToDocs')->willReturn('admin-logging');
65 65
 
66 66
 		$this->config->expects(self::once())
Please login to merge, or discard this patch.
apps/settings/tests/SetupChecks/DataDirectoryProtectedTest.php 2 patches
Indentation   +94 added lines, -94 removed lines patch added patch discarded remove patch
@@ -20,98 +20,98 @@
 block discarded – undo
20 20
 use Test\TestCase;
21 21
 
22 22
 class DataDirectoryProtectedTest extends TestCase {
23
-	private IL10N&MockObject $l10n;
24
-	private IConfig&MockObject $config;
25
-	private IURLGenerator&MockObject $urlGenerator;
26
-	private IClientService&MockObject $clientService;
27
-	private LoggerInterface&MockObject $logger;
28
-	private DataDirectoryProtected&MockObject $setupcheck;
29
-
30
-	protected function setUp(): void {
31
-		parent::setUp();
32
-
33
-		$this->l10n = $this->createMock(IL10N::class);
34
-		$this->l10n->expects($this->any())
35
-			->method('t')
36
-			->willReturnCallback(function ($message, array $replace) {
37
-				return vsprintf($message, $replace);
38
-			});
39
-
40
-		$this->config = $this->createMock(IConfig::class);
41
-		$this->urlGenerator = $this->createMock(IURLGenerator::class);
42
-		$this->clientService = $this->createMock(IClientService::class);
43
-		$this->logger = $this->createMock(LoggerInterface::class);
44
-
45
-		$this->setupcheck = $this->getMockBuilder(DataDirectoryProtected::class)
46
-			->onlyMethods(['runRequest'])
47
-			->setConstructorArgs([
48
-				$this->l10n,
49
-				$this->config,
50
-				$this->urlGenerator,
51
-				$this->clientService,
52
-				$this->logger,
53
-			])
54
-			->getMock();
55
-	}
56
-
57
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataTestStatusCode')]
58
-	public function testStatusCode(array $status, string $expected, bool $hasBody): void {
59
-		$responses = array_map(function ($state) use ($hasBody) {
60
-			$response = $this->createMock(IResponse::class);
61
-			$response->expects($this->any())->method('getStatusCode')->willReturn($state);
62
-			$response->expects(($this->atMost(1)))->method('getBody')->willReturn($hasBody ? '# Nextcloud data directory' : 'something else');
63
-			return $response;
64
-		}, $status);
65
-
66
-		$this->setupcheck
67
-			->expects($this->once())
68
-			->method('runRequest')
69
-			->will($this->generate($responses));
70
-
71
-		$this->config
72
-			->expects($this->once())
73
-			->method('getSystemValueString')
74
-			->willReturn('');
75
-
76
-		$result = $this->setupcheck->run();
77
-		$this->assertEquals($expected, $result->getSeverity());
78
-	}
79
-
80
-	public static function dataTestStatusCode(): array {
81
-		return [
82
-			'success: forbidden access' => [[403], SetupResult::SUCCESS, true],
83
-			'success: forbidden access with redirect' => [[200], SetupResult::SUCCESS, false],
84
-			'error: can access' => [[200], SetupResult::ERROR, true],
85
-			'error: one forbidden one can access' => [[403, 200], SetupResult::ERROR, true],
86
-			'warning: connection issue' => [[], SetupResult::WARNING, true],
87
-		];
88
-	}
89
-
90
-	public function testNoResponse(): void {
91
-		$response = $this->createMock(IResponse::class);
92
-		$response->expects($this->any())->method('getStatusCode')->willReturn(200);
93
-
94
-		$this->setupcheck
95
-			->expects($this->once())
96
-			->method('runRequest')
97
-			->will($this->generate([]));
98
-
99
-		$this->config
100
-			->expects($this->once())
101
-			->method('getSystemValueString')
102
-			->willReturn('');
103
-
104
-		$result = $this->setupcheck->run();
105
-		$this->assertEquals(SetupResult::WARNING, $result->getSeverity());
106
-		$this->assertMatchesRegularExpression('/^Could not check/', $result->getDescription());
107
-	}
108
-
109
-	/**
110
-	 * Helper function creates a nicer interface for mocking Generator behavior
111
-	 */
112
-	protected function generate(array $yield_values) {
113
-		return $this->returnCallback(function () use ($yield_values) {
114
-			yield from $yield_values;
115
-		});
116
-	}
23
+    private IL10N&MockObject $l10n;
24
+    private IConfig&MockObject $config;
25
+    private IURLGenerator&MockObject $urlGenerator;
26
+    private IClientService&MockObject $clientService;
27
+    private LoggerInterface&MockObject $logger;
28
+    private DataDirectoryProtected&MockObject $setupcheck;
29
+
30
+    protected function setUp(): void {
31
+        parent::setUp();
32
+
33
+        $this->l10n = $this->createMock(IL10N::class);
34
+        $this->l10n->expects($this->any())
35
+            ->method('t')
36
+            ->willReturnCallback(function ($message, array $replace) {
37
+                return vsprintf($message, $replace);
38
+            });
39
+
40
+        $this->config = $this->createMock(IConfig::class);
41
+        $this->urlGenerator = $this->createMock(IURLGenerator::class);
42
+        $this->clientService = $this->createMock(IClientService::class);
43
+        $this->logger = $this->createMock(LoggerInterface::class);
44
+
45
+        $this->setupcheck = $this->getMockBuilder(DataDirectoryProtected::class)
46
+            ->onlyMethods(['runRequest'])
47
+            ->setConstructorArgs([
48
+                $this->l10n,
49
+                $this->config,
50
+                $this->urlGenerator,
51
+                $this->clientService,
52
+                $this->logger,
53
+            ])
54
+            ->getMock();
55
+    }
56
+
57
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataTestStatusCode')]
58
+    public function testStatusCode(array $status, string $expected, bool $hasBody): void {
59
+        $responses = array_map(function ($state) use ($hasBody) {
60
+            $response = $this->createMock(IResponse::class);
61
+            $response->expects($this->any())->method('getStatusCode')->willReturn($state);
62
+            $response->expects(($this->atMost(1)))->method('getBody')->willReturn($hasBody ? '# Nextcloud data directory' : 'something else');
63
+            return $response;
64
+        }, $status);
65
+
66
+        $this->setupcheck
67
+            ->expects($this->once())
68
+            ->method('runRequest')
69
+            ->will($this->generate($responses));
70
+
71
+        $this->config
72
+            ->expects($this->once())
73
+            ->method('getSystemValueString')
74
+            ->willReturn('');
75
+
76
+        $result = $this->setupcheck->run();
77
+        $this->assertEquals($expected, $result->getSeverity());
78
+    }
79
+
80
+    public static function dataTestStatusCode(): array {
81
+        return [
82
+            'success: forbidden access' => [[403], SetupResult::SUCCESS, true],
83
+            'success: forbidden access with redirect' => [[200], SetupResult::SUCCESS, false],
84
+            'error: can access' => [[200], SetupResult::ERROR, true],
85
+            'error: one forbidden one can access' => [[403, 200], SetupResult::ERROR, true],
86
+            'warning: connection issue' => [[], SetupResult::WARNING, true],
87
+        ];
88
+    }
89
+
90
+    public function testNoResponse(): void {
91
+        $response = $this->createMock(IResponse::class);
92
+        $response->expects($this->any())->method('getStatusCode')->willReturn(200);
93
+
94
+        $this->setupcheck
95
+            ->expects($this->once())
96
+            ->method('runRequest')
97
+            ->will($this->generate([]));
98
+
99
+        $this->config
100
+            ->expects($this->once())
101
+            ->method('getSystemValueString')
102
+            ->willReturn('');
103
+
104
+        $result = $this->setupcheck->run();
105
+        $this->assertEquals(SetupResult::WARNING, $result->getSeverity());
106
+        $this->assertMatchesRegularExpression('/^Could not check/', $result->getDescription());
107
+    }
108
+
109
+    /**
110
+     * Helper function creates a nicer interface for mocking Generator behavior
111
+     */
112
+    protected function generate(array $yield_values) {
113
+        return $this->returnCallback(function () use ($yield_values) {
114
+            yield from $yield_values;
115
+        });
116
+    }
117 117
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -33,7 +33,7 @@  discard block
 block discarded – undo
33 33
 		$this->l10n = $this->createMock(IL10N::class);
34 34
 		$this->l10n->expects($this->any())
35 35
 			->method('t')
36
-			->willReturnCallback(function ($message, array $replace) {
36
+			->willReturnCallback(function($message, array $replace) {
37 37
 				return vsprintf($message, $replace);
38 38
 			});
39 39
 
@@ -56,7 +56,7 @@  discard block
 block discarded – undo
56 56
 
57 57
 	#[\PHPUnit\Framework\Attributes\DataProvider('dataTestStatusCode')]
58 58
 	public function testStatusCode(array $status, string $expected, bool $hasBody): void {
59
-		$responses = array_map(function ($state) use ($hasBody) {
59
+		$responses = array_map(function($state) use ($hasBody) {
60 60
 			$response = $this->createMock(IResponse::class);
61 61
 			$response->expects($this->any())->method('getStatusCode')->willReturn($state);
62 62
 			$response->expects(($this->atMost(1)))->method('getBody')->willReturn($hasBody ? '# Nextcloud data directory' : 'something else');
@@ -110,7 +110,7 @@  discard block
 block discarded – undo
110 110
 	 * Helper function creates a nicer interface for mocking Generator behavior
111 111
 	 */
112 112
 	protected function generate(array $yield_values) {
113
-		return $this->returnCallback(function () use ($yield_values) {
113
+		return $this->returnCallback(function() use ($yield_values) {
114 114
 			yield from $yield_values;
115 115
 		});
116 116
 	}
Please login to merge, or discard this patch.
apps/settings/tests/SetupChecks/SecurityHeadersTest.php 1 patch
Indentation   +173 added lines, -173 removed lines patch added patch discarded remove patch
@@ -20,177 +20,177 @@
 block discarded – undo
20 20
 use Test\TestCase;
21 21
 
22 22
 class SecurityHeadersTest extends TestCase {
23
-	private IL10N&MockObject $l10n;
24
-	private IConfig&MockObject $config;
25
-	private IURLGenerator&MockObject $urlGenerator;
26
-	private IClientService&MockObject $clientService;
27
-	private LoggerInterface&MockObject $logger;
28
-	private SecurityHeaders&MockObject $setupcheck;
29
-
30
-	protected function setUp(): void {
31
-		parent::setUp();
32
-
33
-		$this->l10n = $this->createMock(IL10N::class);
34
-		$this->l10n->expects($this->any())
35
-			->method('t')
36
-			->willReturnCallback(function ($message, array $replace) {
37
-				return vsprintf($message, $replace);
38
-			});
39
-
40
-		$this->config = $this->createMock(IConfig::class);
41
-		$this->urlGenerator = $this->createMock(IURLGenerator::class);
42
-		$this->clientService = $this->createMock(IClientService::class);
43
-		$this->logger = $this->createMock(LoggerInterface::class);
44
-
45
-		$this->setupcheck = $this->getMockBuilder(SecurityHeaders::class)
46
-			->onlyMethods(['runRequest'])
47
-			->setConstructorArgs([
48
-				$this->l10n,
49
-				$this->config,
50
-				$this->urlGenerator,
51
-				$this->clientService,
52
-				$this->logger,
53
-			])
54
-			->getMock();
55
-	}
56
-
57
-	public function testInvalidStatusCode(): void {
58
-		$this->setupResponse(500, []);
59
-
60
-		$result = $this->setupcheck->run();
61
-		$this->assertMatchesRegularExpression('/^Could not check that your web server serves security headers correctly/', $result->getDescription());
62
-		$this->assertEquals(SetupResult::WARNING, $result->getSeverity());
63
-	}
64
-
65
-	public function testAllHeadersMissing(): void {
66
-		$this->setupResponse(200, []);
67
-
68
-		$result = $this->setupcheck->run();
69
-		$this->assertMatchesRegularExpression('/^Some headers are not set correctly on your instance/', $result->getDescription());
70
-		$this->assertEquals(SetupResult::WARNING, $result->getSeverity());
71
-	}
72
-
73
-	public function testSomeHeadersMissing(): void {
74
-		$this->setupResponse(
75
-			200,
76
-			[
77
-				'X-Robots-Tag' => 'noindex, nofollow',
78
-				'X-Frame-Options' => 'SAMEORIGIN',
79
-				'Strict-Transport-Security' => 'max-age=15768000;preload',
80
-				'X-Permitted-Cross-Domain-Policies' => 'none',
81
-				'Referrer-Policy' => 'no-referrer',
82
-			]
83
-		);
84
-
85
-		$result = $this->setupcheck->run();
86
-		$this->assertEquals(
87
-			"Some headers are not set correctly on your instance\n- The `X-Content-Type-Options` HTTP header is not set to `nosniff`. This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.\n",
88
-			$result->getDescription()
89
-		);
90
-		$this->assertEquals(SetupResult::WARNING, $result->getSeverity());
91
-	}
92
-
93
-	public static function dataSuccess(): array {
94
-		return [
95
-			// description => modifiedHeaders
96
-			'basic' => [[]],
97
-			'no-space-in-x-robots' => [['X-Robots-Tag' => 'noindex,nofollow']],
98
-			'strict-origin-when-cross-origin' => [['Referrer-Policy' => 'strict-origin-when-cross-origin']],
99
-			'referrer-no-referrer-when-downgrade' => [['Referrer-Policy' => 'no-referrer-when-downgrade']],
100
-			'referrer-strict-origin' => [['Referrer-Policy' => 'strict-origin']],
101
-			'referrer-strict-origin-when-cross-origin' => [['Referrer-Policy' => 'strict-origin-when-cross-origin']],
102
-			'referrer-same-origin' => [['Referrer-Policy' => 'same-origin']],
103
-			'hsts-minimum' => [['Strict-Transport-Security' => 'max-age=15552000']],
104
-			'hsts-include-subdomains' => [['Strict-Transport-Security' => 'max-age=99999999; includeSubDomains']],
105
-			'hsts-include-subdomains-preload' => [['Strict-Transport-Security' => 'max-age=99999999; preload; includeSubDomains']],
106
-		];
107
-	}
108
-
109
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataSuccess')]
110
-	public function testSuccess(array $headers): void {
111
-		$headers = array_merge(
112
-			[
113
-				'X-Content-Type-Options' => 'nosniff',
114
-				'X-Robots-Tag' => 'noindex, nofollow',
115
-				'X-Frame-Options' => 'SAMEORIGIN',
116
-				'Strict-Transport-Security' => 'max-age=15768000',
117
-				'X-Permitted-Cross-Domain-Policies' => 'none',
118
-				'Referrer-Policy' => 'no-referrer',
119
-			],
120
-			$headers
121
-		);
122
-		$this->setupResponse(
123
-			200,
124
-			$headers
125
-		);
126
-
127
-		$result = $this->setupcheck->run();
128
-		$this->assertEquals(
129
-			'Your server is correctly configured to send security headers.',
130
-			$result->getDescription()
131
-		);
132
-		$this->assertEquals(SetupResult::SUCCESS, $result->getSeverity());
133
-	}
134
-
135
-	public static function dataFailure(): array {
136
-		return [
137
-			// description => modifiedHeaders
138
-			'x-robots-none' => [['X-Robots-Tag' => 'none'], "- The `X-Robots-Tag` HTTP header is not set to `noindex,nofollow`. This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.\n"],
139
-			'referrer-origin' => [['Referrer-Policy' => 'origin'], "- The `Referrer-Policy` HTTP header is not set to `no-referrer`, `no-referrer-when-downgrade`, `strict-origin`, `strict-origin-when-cross-origin` or `same-origin`. This can leak referer information. See the {w3c-recommendation}.\n"],
140
-			'referrer-origin-when-cross-origin' => [['Referrer-Policy' => 'origin-when-cross-origin'], "- The `Referrer-Policy` HTTP header is not set to `no-referrer`, `no-referrer-when-downgrade`, `strict-origin`, `strict-origin-when-cross-origin` or `same-origin`. This can leak referer information. See the {w3c-recommendation}.\n"],
141
-			'referrer-unsafe-url' => [['Referrer-Policy' => 'unsafe-url'], "- The `Referrer-Policy` HTTP header is not set to `no-referrer`, `no-referrer-when-downgrade`, `strict-origin`, `strict-origin-when-cross-origin` or `same-origin`. This can leak referer information. See the {w3c-recommendation}.\n"],
142
-			'hsts-missing' => [['Strict-Transport-Security' => ''], "- The `Strict-Transport-Security` HTTP header is not set (should be at least `15552000` seconds). For enhanced security, it is recommended to enable HSTS.\n"],
143
-			'hsts-too-low' => [['Strict-Transport-Security' => 'max-age=15551999'], "- The `Strict-Transport-Security` HTTP header is not set to at least `15552000` seconds (current value: `15551999`). For enhanced security, it is recommended to use a long HSTS policy.\n"],
144
-			'hsts-malformed' => [['Strict-Transport-Security' => 'iAmABogusHeader342'], "- The `Strict-Transport-Security` HTTP header is malformed: `iAmABogusHeader342`. For enhanced security, it is recommended to enable HSTS.\n"],
145
-		];
146
-	}
147
-
148
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataFailure')]
149
-	public function testFailure(array $headers, string $msg): void {
150
-		$headers = array_merge(
151
-			[
152
-				'X-Content-Type-Options' => 'nosniff',
153
-				'X-Robots-Tag' => 'noindex, nofollow',
154
-				'X-Frame-Options' => 'SAMEORIGIN',
155
-				'Strict-Transport-Security' => 'max-age=15768000',
156
-				'X-Permitted-Cross-Domain-Policies' => 'none',
157
-				'Referrer-Policy' => 'no-referrer',
158
-			],
159
-			$headers
160
-		);
161
-		$this->setupResponse(
162
-			200,
163
-			$headers
164
-		);
165
-
166
-		$result = $this->setupcheck->run();
167
-		$this->assertEquals(
168
-			'Some headers are not set correctly on your instance' . "\n$msg",
169
-			$result->getDescription()
170
-		);
171
-		$this->assertEquals(SetupResult::WARNING, $result->getSeverity());
172
-	}
173
-
174
-	protected function setupResponse(int $statuscode, array $headers): void {
175
-		$response = $this->createMock(IResponse::class);
176
-		$response->expects($this->atLeastOnce())->method('getStatusCode')->willReturn($statuscode);
177
-		$response->expects($this->any())->method('getHeader')
178
-			->willReturnCallback(
179
-				fn (string $header): string => $headers[$header] ?? ''
180
-			);
181
-
182
-		$this->setupcheck
183
-			->expects($this->atLeastOnce())
184
-			->method('runRequest')
185
-			->willReturnOnConsecutiveCalls($this->generate([$response]));
186
-	}
187
-
188
-	/**
189
-	 * Helper function creates a nicer interface for mocking Generator behavior
190
-	 */
191
-	protected function generate(array $yield_values) {
192
-		return $this->returnCallback(function () use ($yield_values) {
193
-			yield from $yield_values;
194
-		});
195
-	}
23
+    private IL10N&MockObject $l10n;
24
+    private IConfig&MockObject $config;
25
+    private IURLGenerator&MockObject $urlGenerator;
26
+    private IClientService&MockObject $clientService;
27
+    private LoggerInterface&MockObject $logger;
28
+    private SecurityHeaders&MockObject $setupcheck;
29
+
30
+    protected function setUp(): void {
31
+        parent::setUp();
32
+
33
+        $this->l10n = $this->createMock(IL10N::class);
34
+        $this->l10n->expects($this->any())
35
+            ->method('t')
36
+            ->willReturnCallback(function ($message, array $replace) {
37
+                return vsprintf($message, $replace);
38
+            });
39
+
40
+        $this->config = $this->createMock(IConfig::class);
41
+        $this->urlGenerator = $this->createMock(IURLGenerator::class);
42
+        $this->clientService = $this->createMock(IClientService::class);
43
+        $this->logger = $this->createMock(LoggerInterface::class);
44
+
45
+        $this->setupcheck = $this->getMockBuilder(SecurityHeaders::class)
46
+            ->onlyMethods(['runRequest'])
47
+            ->setConstructorArgs([
48
+                $this->l10n,
49
+                $this->config,
50
+                $this->urlGenerator,
51
+                $this->clientService,
52
+                $this->logger,
53
+            ])
54
+            ->getMock();
55
+    }
56
+
57
+    public function testInvalidStatusCode(): void {
58
+        $this->setupResponse(500, []);
59
+
60
+        $result = $this->setupcheck->run();
61
+        $this->assertMatchesRegularExpression('/^Could not check that your web server serves security headers correctly/', $result->getDescription());
62
+        $this->assertEquals(SetupResult::WARNING, $result->getSeverity());
63
+    }
64
+
65
+    public function testAllHeadersMissing(): void {
66
+        $this->setupResponse(200, []);
67
+
68
+        $result = $this->setupcheck->run();
69
+        $this->assertMatchesRegularExpression('/^Some headers are not set correctly on your instance/', $result->getDescription());
70
+        $this->assertEquals(SetupResult::WARNING, $result->getSeverity());
71
+    }
72
+
73
+    public function testSomeHeadersMissing(): void {
74
+        $this->setupResponse(
75
+            200,
76
+            [
77
+                'X-Robots-Tag' => 'noindex, nofollow',
78
+                'X-Frame-Options' => 'SAMEORIGIN',
79
+                'Strict-Transport-Security' => 'max-age=15768000;preload',
80
+                'X-Permitted-Cross-Domain-Policies' => 'none',
81
+                'Referrer-Policy' => 'no-referrer',
82
+            ]
83
+        );
84
+
85
+        $result = $this->setupcheck->run();
86
+        $this->assertEquals(
87
+            "Some headers are not set correctly on your instance\n- The `X-Content-Type-Options` HTTP header is not set to `nosniff`. This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.\n",
88
+            $result->getDescription()
89
+        );
90
+        $this->assertEquals(SetupResult::WARNING, $result->getSeverity());
91
+    }
92
+
93
+    public static function dataSuccess(): array {
94
+        return [
95
+            // description => modifiedHeaders
96
+            'basic' => [[]],
97
+            'no-space-in-x-robots' => [['X-Robots-Tag' => 'noindex,nofollow']],
98
+            'strict-origin-when-cross-origin' => [['Referrer-Policy' => 'strict-origin-when-cross-origin']],
99
+            'referrer-no-referrer-when-downgrade' => [['Referrer-Policy' => 'no-referrer-when-downgrade']],
100
+            'referrer-strict-origin' => [['Referrer-Policy' => 'strict-origin']],
101
+            'referrer-strict-origin-when-cross-origin' => [['Referrer-Policy' => 'strict-origin-when-cross-origin']],
102
+            'referrer-same-origin' => [['Referrer-Policy' => 'same-origin']],
103
+            'hsts-minimum' => [['Strict-Transport-Security' => 'max-age=15552000']],
104
+            'hsts-include-subdomains' => [['Strict-Transport-Security' => 'max-age=99999999; includeSubDomains']],
105
+            'hsts-include-subdomains-preload' => [['Strict-Transport-Security' => 'max-age=99999999; preload; includeSubDomains']],
106
+        ];
107
+    }
108
+
109
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataSuccess')]
110
+    public function testSuccess(array $headers): void {
111
+        $headers = array_merge(
112
+            [
113
+                'X-Content-Type-Options' => 'nosniff',
114
+                'X-Robots-Tag' => 'noindex, nofollow',
115
+                'X-Frame-Options' => 'SAMEORIGIN',
116
+                'Strict-Transport-Security' => 'max-age=15768000',
117
+                'X-Permitted-Cross-Domain-Policies' => 'none',
118
+                'Referrer-Policy' => 'no-referrer',
119
+            ],
120
+            $headers
121
+        );
122
+        $this->setupResponse(
123
+            200,
124
+            $headers
125
+        );
126
+
127
+        $result = $this->setupcheck->run();
128
+        $this->assertEquals(
129
+            'Your server is correctly configured to send security headers.',
130
+            $result->getDescription()
131
+        );
132
+        $this->assertEquals(SetupResult::SUCCESS, $result->getSeverity());
133
+    }
134
+
135
+    public static function dataFailure(): array {
136
+        return [
137
+            // description => modifiedHeaders
138
+            'x-robots-none' => [['X-Robots-Tag' => 'none'], "- The `X-Robots-Tag` HTTP header is not set to `noindex,nofollow`. This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.\n"],
139
+            'referrer-origin' => [['Referrer-Policy' => 'origin'], "- The `Referrer-Policy` HTTP header is not set to `no-referrer`, `no-referrer-when-downgrade`, `strict-origin`, `strict-origin-when-cross-origin` or `same-origin`. This can leak referer information. See the {w3c-recommendation}.\n"],
140
+            'referrer-origin-when-cross-origin' => [['Referrer-Policy' => 'origin-when-cross-origin'], "- The `Referrer-Policy` HTTP header is not set to `no-referrer`, `no-referrer-when-downgrade`, `strict-origin`, `strict-origin-when-cross-origin` or `same-origin`. This can leak referer information. See the {w3c-recommendation}.\n"],
141
+            'referrer-unsafe-url' => [['Referrer-Policy' => 'unsafe-url'], "- The `Referrer-Policy` HTTP header is not set to `no-referrer`, `no-referrer-when-downgrade`, `strict-origin`, `strict-origin-when-cross-origin` or `same-origin`. This can leak referer information. See the {w3c-recommendation}.\n"],
142
+            'hsts-missing' => [['Strict-Transport-Security' => ''], "- The `Strict-Transport-Security` HTTP header is not set (should be at least `15552000` seconds). For enhanced security, it is recommended to enable HSTS.\n"],
143
+            'hsts-too-low' => [['Strict-Transport-Security' => 'max-age=15551999'], "- The `Strict-Transport-Security` HTTP header is not set to at least `15552000` seconds (current value: `15551999`). For enhanced security, it is recommended to use a long HSTS policy.\n"],
144
+            'hsts-malformed' => [['Strict-Transport-Security' => 'iAmABogusHeader342'], "- The `Strict-Transport-Security` HTTP header is malformed: `iAmABogusHeader342`. For enhanced security, it is recommended to enable HSTS.\n"],
145
+        ];
146
+    }
147
+
148
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataFailure')]
149
+    public function testFailure(array $headers, string $msg): void {
150
+        $headers = array_merge(
151
+            [
152
+                'X-Content-Type-Options' => 'nosniff',
153
+                'X-Robots-Tag' => 'noindex, nofollow',
154
+                'X-Frame-Options' => 'SAMEORIGIN',
155
+                'Strict-Transport-Security' => 'max-age=15768000',
156
+                'X-Permitted-Cross-Domain-Policies' => 'none',
157
+                'Referrer-Policy' => 'no-referrer',
158
+            ],
159
+            $headers
160
+        );
161
+        $this->setupResponse(
162
+            200,
163
+            $headers
164
+        );
165
+
166
+        $result = $this->setupcheck->run();
167
+        $this->assertEquals(
168
+            'Some headers are not set correctly on your instance' . "\n$msg",
169
+            $result->getDescription()
170
+        );
171
+        $this->assertEquals(SetupResult::WARNING, $result->getSeverity());
172
+    }
173
+
174
+    protected function setupResponse(int $statuscode, array $headers): void {
175
+        $response = $this->createMock(IResponse::class);
176
+        $response->expects($this->atLeastOnce())->method('getStatusCode')->willReturn($statuscode);
177
+        $response->expects($this->any())->method('getHeader')
178
+            ->willReturnCallback(
179
+                fn (string $header): string => $headers[$header] ?? ''
180
+            );
181
+
182
+        $this->setupcheck
183
+            ->expects($this->atLeastOnce())
184
+            ->method('runRequest')
185
+            ->willReturnOnConsecutiveCalls($this->generate([$response]));
186
+    }
187
+
188
+    /**
189
+     * Helper function creates a nicer interface for mocking Generator behavior
190
+     */
191
+    protected function generate(array $yield_values) {
192
+        return $this->returnCallback(function () use ($yield_values) {
193
+            yield from $yield_values;
194
+        });
195
+    }
196 196
 }
Please login to merge, or discard this patch.
apps/settings/tests/SetupChecks/WellKnownUrlsTest.php 1 patch
Indentation   +192 added lines, -192 removed lines patch added patch discarded remove patch
@@ -20,196 +20,196 @@
 block discarded – undo
20 20
 use Test\TestCase;
21 21
 
22 22
 class WellKnownUrlsTest extends TestCase {
23
-	private IL10N&MockObject $l10n;
24
-	private IConfig&MockObject $config;
25
-	private IURLGenerator&MockObject $urlGenerator;
26
-	private IClientService&MockObject $clientService;
27
-	private LoggerInterface&MockObject $logger;
28
-	private WellKnownUrls&MockObject $setupcheck;
29
-
30
-	protected function setUp(): void {
31
-		parent::setUp();
32
-
33
-		/** @var IL10N&MockObject */
34
-		$this->l10n = $this->createMock(IL10N::class);
35
-		$this->l10n->expects($this->any())
36
-			->method('t')
37
-			->willReturnCallback(function ($message, array $replace) {
38
-				return vsprintf($message, $replace);
39
-			});
40
-
41
-		$this->config = $this->createMock(IConfig::class);
42
-		$this->urlGenerator = $this->createMock(IURLGenerator::class);
43
-		$this->clientService = $this->createMock(IClientService::class);
44
-		$this->logger = $this->createMock(LoggerInterface::class);
45
-
46
-		$this->setupcheck = $this->getMockBuilder(WellKnownUrls::class)
47
-			->onlyMethods(['runRequest'])
48
-			->setConstructorArgs([
49
-				$this->l10n,
50
-				$this->config,
51
-				$this->urlGenerator,
52
-				$this->clientService,
53
-				$this->logger,
54
-			])
55
-			->getMock();
56
-	}
57
-
58
-	/**
59
-	 * Test that the SetupCheck is skipped if the system config is set
60
-	 */
61
-	public function testDisabled(): void {
62
-		$this->config
63
-			->expects($this->once())
64
-			->method('getSystemValueBool')
65
-			->with('check_for_working_wellknown_setup')
66
-			->willReturn(false);
67
-
68
-		$this->setupcheck
69
-			->expects($this->never())
70
-			->method('runRequest');
71
-
72
-		$result = $this->setupcheck->run();
73
-		$this->assertEquals(SetupResult::INFO, $result->getSeverity());
74
-		$this->assertMatchesRegularExpression('/check was skipped/', $result->getDescription());
75
-	}
76
-
77
-	/**
78
-	 * Test what happens if the local server could not be reached (no response from the requests)
79
-	 */
80
-	public function testNoResponse(): void {
81
-		$this->config
82
-			->expects($this->once())
83
-			->method('getSystemValueBool')
84
-			->with('check_for_working_wellknown_setup')
85
-			->willReturn(true);
86
-
87
-		$this->setupcheck
88
-			->expects($this->once())
89
-			->method('runRequest')
90
-			->will($this->generate([]));
91
-
92
-		$result = $this->setupcheck->run();
93
-		$this->assertEquals(SetupResult::INFO, $result->getSeverity());
94
-		$this->assertMatchesRegularExpression('/^Could not check/', $result->getDescription());
95
-	}
96
-
97
-	/**
98
-	 * Test responses
99
-	 */
100
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataTestResponses')]
101
-	public function testResponses($responses, string $expectedSeverity): void {
102
-		$this->config
103
-			->expects($this->once())
104
-			->method('getSystemValueBool')
105
-			->with('check_for_working_wellknown_setup')
106
-			->willReturn(true);
107
-
108
-		$this->setupcheck
109
-			->expects($this->atLeastOnce())
110
-			->method('runRequest')
111
-			->willReturnOnConsecutiveCalls(...$responses);
112
-
113
-		$result = $this->setupcheck->run();
114
-		$this->assertEquals($expectedSeverity, $result->getSeverity());
115
-	}
116
-
117
-	public function dataTestResponses(): array {
118
-		$createResponse = function (int $statuscode, array $header = []): IResponse&MockObject {
119
-			$response = $this->createMock(IResponse::class);
120
-			$response->expects($this->any())
121
-				->method('getStatusCode')
122
-				->willReturn($statuscode);
123
-			$response->expects($this->any())
124
-				->method('getHeader')
125
-				->willReturnCallback(fn ($name) => $header[$name] ?? '');
126
-			return $response;
127
-		};
128
-
129
-		$wellKnownHeader = ['X-NEXTCLOUD-WELL-KNOWN' => 'yes'];
130
-
131
-		return [
132
-			'expected codes' => [
133
-				[
134
-					$this->generate([$createResponse(200, $wellKnownHeader)]),
135
-					$this->generate([$createResponse(200, $wellKnownHeader)]),
136
-					$this->generate([$createResponse(207)]),
137
-					$this->generate([$createResponse(207)]),
138
-				],
139
-				SetupResult::SUCCESS,
140
-			],
141
-			'late response with expected codes' => [
142
-				[
143
-					$this->generate([$createResponse(404), $createResponse(200, $wellKnownHeader)]),
144
-					$this->generate([$createResponse(404), $createResponse(200, $wellKnownHeader)]),
145
-					$this->generate([$createResponse(404), $createResponse(207)]),
146
-					$this->generate([$createResponse(404), $createResponse(207)]),
147
-				],
148
-				SetupResult::SUCCESS,
149
-			],
150
-			'working but disabled webfinger' => [
151
-				[
152
-					$this->generate([$createResponse(404, $wellKnownHeader)]),
153
-					$this->generate([$createResponse(404, $wellKnownHeader)]),
154
-					$this->generate([$createResponse(207)]),
155
-					$this->generate([$createResponse(207)]),
156
-				],
157
-				SetupResult::SUCCESS,
158
-			],
159
-			'unauthorized webdav but with correct configured redirect' => [
160
-				[
161
-					$this->generate([$createResponse(404, $wellKnownHeader)]),
162
-					$this->generate([$createResponse(404, $wellKnownHeader)]),
163
-					$this->generate([$createResponse(401, ['X-Guzzle-Redirect-History' => 'https://example.com,https://example.com/remote.php/dav/'])]),
164
-					$this->generate([$createResponse(401, ['X-Guzzle-Redirect-History' => 'https://example.com/remote.php/dav/'])]),
165
-				],
166
-				SetupResult::SUCCESS,
167
-			],
168
-			'not configured path' => [
169
-				[
170
-					$this->generate([$createResponse(404)]),
171
-					$this->generate([$createResponse(404)]),
172
-					$this->generate([$createResponse(404)]),
173
-					$this->generate([$createResponse(404)]),
174
-				],
175
-				SetupResult::WARNING,
176
-			],
177
-			'Invalid webfinger' => [
178
-				[
179
-					$this->generate([$createResponse(404)]),
180
-					$this->generate([$createResponse(404, $wellKnownHeader)]),
181
-					$this->generate([$createResponse(207)]),
182
-					$this->generate([$createResponse(207)]),
183
-				],
184
-				SetupResult::WARNING,
185
-			],
186
-			'Invalid nodeinfo' => [
187
-				[
188
-					$this->generate([$createResponse(404, $wellKnownHeader)]),
189
-					$this->generate([$createResponse(404)]),
190
-					$this->generate([$createResponse(207)]),
191
-					$this->generate([$createResponse(207)]),
192
-				],
193
-				SetupResult::WARNING,
194
-			],
195
-			'Invalid caldav' => [
196
-				[
197
-					$this->generate([$createResponse(404, $wellKnownHeader)]),
198
-					$this->generate([$createResponse(404, $wellKnownHeader)]),
199
-					$this->generate([$createResponse(404)]),
200
-					$this->generate([$createResponse(207)]),
201
-				],
202
-				SetupResult::WARNING,
203
-			],
204
-		];
205
-	}
206
-
207
-	/**
208
-	 * Helper function creates a nicer interface for mocking Generator behavior
209
-	 */
210
-	protected function generate(array $yield_values) {
211
-		return $this->returnCallback(function () use ($yield_values) {
212
-			yield from $yield_values;
213
-		});
214
-	}
23
+    private IL10N&MockObject $l10n;
24
+    private IConfig&MockObject $config;
25
+    private IURLGenerator&MockObject $urlGenerator;
26
+    private IClientService&MockObject $clientService;
27
+    private LoggerInterface&MockObject $logger;
28
+    private WellKnownUrls&MockObject $setupcheck;
29
+
30
+    protected function setUp(): void {
31
+        parent::setUp();
32
+
33
+        /** @var IL10N&MockObject */
34
+        $this->l10n = $this->createMock(IL10N::class);
35
+        $this->l10n->expects($this->any())
36
+            ->method('t')
37
+            ->willReturnCallback(function ($message, array $replace) {
38
+                return vsprintf($message, $replace);
39
+            });
40
+
41
+        $this->config = $this->createMock(IConfig::class);
42
+        $this->urlGenerator = $this->createMock(IURLGenerator::class);
43
+        $this->clientService = $this->createMock(IClientService::class);
44
+        $this->logger = $this->createMock(LoggerInterface::class);
45
+
46
+        $this->setupcheck = $this->getMockBuilder(WellKnownUrls::class)
47
+            ->onlyMethods(['runRequest'])
48
+            ->setConstructorArgs([
49
+                $this->l10n,
50
+                $this->config,
51
+                $this->urlGenerator,
52
+                $this->clientService,
53
+                $this->logger,
54
+            ])
55
+            ->getMock();
56
+    }
57
+
58
+    /**
59
+     * Test that the SetupCheck is skipped if the system config is set
60
+     */
61
+    public function testDisabled(): void {
62
+        $this->config
63
+            ->expects($this->once())
64
+            ->method('getSystemValueBool')
65
+            ->with('check_for_working_wellknown_setup')
66
+            ->willReturn(false);
67
+
68
+        $this->setupcheck
69
+            ->expects($this->never())
70
+            ->method('runRequest');
71
+
72
+        $result = $this->setupcheck->run();
73
+        $this->assertEquals(SetupResult::INFO, $result->getSeverity());
74
+        $this->assertMatchesRegularExpression('/check was skipped/', $result->getDescription());
75
+    }
76
+
77
+    /**
78
+     * Test what happens if the local server could not be reached (no response from the requests)
79
+     */
80
+    public function testNoResponse(): void {
81
+        $this->config
82
+            ->expects($this->once())
83
+            ->method('getSystemValueBool')
84
+            ->with('check_for_working_wellknown_setup')
85
+            ->willReturn(true);
86
+
87
+        $this->setupcheck
88
+            ->expects($this->once())
89
+            ->method('runRequest')
90
+            ->will($this->generate([]));
91
+
92
+        $result = $this->setupcheck->run();
93
+        $this->assertEquals(SetupResult::INFO, $result->getSeverity());
94
+        $this->assertMatchesRegularExpression('/^Could not check/', $result->getDescription());
95
+    }
96
+
97
+    /**
98
+     * Test responses
99
+     */
100
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataTestResponses')]
101
+    public function testResponses($responses, string $expectedSeverity): void {
102
+        $this->config
103
+            ->expects($this->once())
104
+            ->method('getSystemValueBool')
105
+            ->with('check_for_working_wellknown_setup')
106
+            ->willReturn(true);
107
+
108
+        $this->setupcheck
109
+            ->expects($this->atLeastOnce())
110
+            ->method('runRequest')
111
+            ->willReturnOnConsecutiveCalls(...$responses);
112
+
113
+        $result = $this->setupcheck->run();
114
+        $this->assertEquals($expectedSeverity, $result->getSeverity());
115
+    }
116
+
117
+    public function dataTestResponses(): array {
118
+        $createResponse = function (int $statuscode, array $header = []): IResponse&MockObject {
119
+            $response = $this->createMock(IResponse::class);
120
+            $response->expects($this->any())
121
+                ->method('getStatusCode')
122
+                ->willReturn($statuscode);
123
+            $response->expects($this->any())
124
+                ->method('getHeader')
125
+                ->willReturnCallback(fn ($name) => $header[$name] ?? '');
126
+            return $response;
127
+        };
128
+
129
+        $wellKnownHeader = ['X-NEXTCLOUD-WELL-KNOWN' => 'yes'];
130
+
131
+        return [
132
+            'expected codes' => [
133
+                [
134
+                    $this->generate([$createResponse(200, $wellKnownHeader)]),
135
+                    $this->generate([$createResponse(200, $wellKnownHeader)]),
136
+                    $this->generate([$createResponse(207)]),
137
+                    $this->generate([$createResponse(207)]),
138
+                ],
139
+                SetupResult::SUCCESS,
140
+            ],
141
+            'late response with expected codes' => [
142
+                [
143
+                    $this->generate([$createResponse(404), $createResponse(200, $wellKnownHeader)]),
144
+                    $this->generate([$createResponse(404), $createResponse(200, $wellKnownHeader)]),
145
+                    $this->generate([$createResponse(404), $createResponse(207)]),
146
+                    $this->generate([$createResponse(404), $createResponse(207)]),
147
+                ],
148
+                SetupResult::SUCCESS,
149
+            ],
150
+            'working but disabled webfinger' => [
151
+                [
152
+                    $this->generate([$createResponse(404, $wellKnownHeader)]),
153
+                    $this->generate([$createResponse(404, $wellKnownHeader)]),
154
+                    $this->generate([$createResponse(207)]),
155
+                    $this->generate([$createResponse(207)]),
156
+                ],
157
+                SetupResult::SUCCESS,
158
+            ],
159
+            'unauthorized webdav but with correct configured redirect' => [
160
+                [
161
+                    $this->generate([$createResponse(404, $wellKnownHeader)]),
162
+                    $this->generate([$createResponse(404, $wellKnownHeader)]),
163
+                    $this->generate([$createResponse(401, ['X-Guzzle-Redirect-History' => 'https://example.com,https://example.com/remote.php/dav/'])]),
164
+                    $this->generate([$createResponse(401, ['X-Guzzle-Redirect-History' => 'https://example.com/remote.php/dav/'])]),
165
+                ],
166
+                SetupResult::SUCCESS,
167
+            ],
168
+            'not configured path' => [
169
+                [
170
+                    $this->generate([$createResponse(404)]),
171
+                    $this->generate([$createResponse(404)]),
172
+                    $this->generate([$createResponse(404)]),
173
+                    $this->generate([$createResponse(404)]),
174
+                ],
175
+                SetupResult::WARNING,
176
+            ],
177
+            'Invalid webfinger' => [
178
+                [
179
+                    $this->generate([$createResponse(404)]),
180
+                    $this->generate([$createResponse(404, $wellKnownHeader)]),
181
+                    $this->generate([$createResponse(207)]),
182
+                    $this->generate([$createResponse(207)]),
183
+                ],
184
+                SetupResult::WARNING,
185
+            ],
186
+            'Invalid nodeinfo' => [
187
+                [
188
+                    $this->generate([$createResponse(404, $wellKnownHeader)]),
189
+                    $this->generate([$createResponse(404)]),
190
+                    $this->generate([$createResponse(207)]),
191
+                    $this->generate([$createResponse(207)]),
192
+                ],
193
+                SetupResult::WARNING,
194
+            ],
195
+            'Invalid caldav' => [
196
+                [
197
+                    $this->generate([$createResponse(404, $wellKnownHeader)]),
198
+                    $this->generate([$createResponse(404, $wellKnownHeader)]),
199
+                    $this->generate([$createResponse(404)]),
200
+                    $this->generate([$createResponse(207)]),
201
+                ],
202
+                SetupResult::WARNING,
203
+            ],
204
+        ];
205
+    }
206
+
207
+    /**
208
+     * Helper function creates a nicer interface for mocking Generator behavior
209
+     */
210
+    protected function generate(array $yield_values) {
211
+        return $this->returnCallback(function () use ($yield_values) {
212
+            yield from $yield_values;
213
+        });
214
+    }
215 215
 }
Please login to merge, or discard this patch.