Browse Source
feat(settings): Migrate OCM / OCS provider tests to SetupCheck
feat(settings): Migrate OCM / OCS provider tests to SetupCheck
Co-authored-by: Ferdinand Thiessen <opensource@fthiessen.de> Co-authored-by: Joas Schilling <213943+nickvergessen@users.noreply.github.com> Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>pull/43607/head
No known key found for this signature in database
GPG Key ID: 45FAE7268762B400
8 changed files with 275 additions and 81 deletions
-
1apps/settings/composer/composer/autoload_classmap.php
-
1apps/settings/composer/composer/autoload_static.php
-
2apps/settings/lib/AppInfo/Application.php
-
99apps/settings/lib/SetupChecks/OcxProviders.php
-
6apps/settings/src/admin.js
-
170apps/settings/tests/SetupChecks/OcxProvicersTest.php
-
41core/js/setupchecks.js
-
36core/js/tests/specs/setupchecksSpec.js
@ -0,0 +1,99 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
/** |
|||
* @copyright Copyright (c) 2024 Ferdinand Thiessen <opensource@fthiessen.de> |
|||
* |
|||
* @author Ferdinand Thiessen <opensource@fthiessen.de> |
|||
* |
|||
* @license AGPL-3.0-or-later |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License as |
|||
* published by the Free Software Foundation, either version 3 of the |
|||
* License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
* |
|||
*/ |
|||
namespace OCA\Settings\SetupChecks; |
|||
|
|||
use OCP\Http\Client\IClientService; |
|||
use OCP\IConfig; |
|||
use OCP\IL10N; |
|||
use OCP\IURLGenerator; |
|||
use OCP\SetupCheck\ISetupCheck; |
|||
use OCP\SetupCheck\SetupResult; |
|||
use Psr\Log\LoggerInterface; |
|||
|
|||
/** |
|||
* Checks if the webserver serves the OCM and OCS providers |
|||
*/ |
|||
class OcxProviders implements ISetupCheck { |
|||
use CheckServerResponseTrait; |
|||
|
|||
public function __construct( |
|||
protected IL10N $l10n, |
|||
protected IConfig $config, |
|||
protected IURLGenerator $urlGenerator, |
|||
protected IClientService $clientService, |
|||
protected LoggerInterface $logger, |
|||
) { |
|||
} |
|||
|
|||
public function getCategory(): string { |
|||
return 'network'; |
|||
} |
|||
|
|||
public function getName(): string { |
|||
return $this->l10n->t('OCS provider resolving'); |
|||
} |
|||
|
|||
public function run(): SetupResult { |
|||
// List of providers that work
|
|||
$workingProviders = []; |
|||
// List of providers we tested (in case one or multiple do not yield any response)
|
|||
$testedProviders = []; |
|||
// All providers that we need to test
|
|||
$providers = [ |
|||
'/ocm-provider/', |
|||
'/ocs-provider/', |
|||
]; |
|||
|
|||
foreach ($providers as $provider) { |
|||
foreach ($this->runHEAD($this->urlGenerator->getWebroot() . $provider) as $response) { |
|||
$testedProviders[$provider] = true; |
|||
if ($response->getStatusCode() === 200) { |
|||
$workingProviders[] = $provider; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (count($testedProviders) < count($providers)) { |
|||
return SetupResult::warning( |
|||
$this->l10n->t('Could not check if your web server properly resolves the OCM and OCS provider URLs.', ) . "\n" . $this->serverConfigHelp(), |
|||
); |
|||
} |
|||
|
|||
$missingProviders = array_diff($providers, $workingProviders); |
|||
if (empty($missingProviders)) { |
|||
return SetupResult::success(); |
|||
} |
|||
|
|||
return SetupResult::warning( |
|||
$this->l10n->t('Your web server is not properly set up to resolve %1$s. |
|||
This is most likely related to a web server configuration that was not updated to deliver this folder directly. |
|||
Please compare your configuration against the shipped rewrite rules in ".htaccess" for Apache or the provided one in the documentation for Nginx. |
|||
On Nginx those are typically the lines starting with "location ~" that need an update.', [join(', ', array_map(fn ($s) => '"'.$s.'"', $missingProviders))]), |
|||
$this->urlGenerator->linkToDocs('admin-nginx'), |
|||
); |
|||
} |
|||
} |
|||
@ -0,0 +1,170 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
/** |
|||
* @copyright Copyright (c) 2024 Ferdinand Thiessen <opensource@fthiessen.de> |
|||
* |
|||
* @author Ferdinand Thiessen <opensource@fthiessen.de> |
|||
* |
|||
* @license AGPL-3.0-or-later |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License as |
|||
* published by the Free Software Foundation, either version 3 of the |
|||
* License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
* |
|||
*/ |
|||
namespace OCA\Settings\Tests; |
|||
|
|||
use OCA\Settings\SetupChecks\OcxProviders; |
|||
use OCP\Http\Client\IClientService; |
|||
use OCP\Http\Client\IResponse; |
|||
use OCP\IConfig; |
|||
use OCP\IL10N; |
|||
use OCP\IURLGenerator; |
|||
use OCP\SetupCheck\SetupResult; |
|||
use PHPUnit\Framework\MockObject\MockObject; |
|||
use Psr\Log\LoggerInterface; |
|||
use Test\TestCase; |
|||
|
|||
class OcxProvicersTest extends TestCase { |
|||
private IL10N|MockObject $l10n; |
|||
private IConfig|MockObject $config; |
|||
private IURLGenerator|MockObject $urlGenerator; |
|||
private IClientService|MockObject $clientService; |
|||
private LoggerInterface|MockObject $logger; |
|||
private OcxProviders|MockObject $setupcheck; |
|||
|
|||
protected function setUp(): void { |
|||
parent::setUp(); |
|||
|
|||
/** @var IL10N|MockObject */ |
|||
$this->l10n = $this->getMockBuilder(IL10N::class) |
|||
->disableOriginalConstructor()->getMock(); |
|||
$this->l10n->expects($this->any()) |
|||
->method('t') |
|||
->willReturnCallback(function ($message, array $replace) { |
|||
return vsprintf($message, $replace); |
|||
}); |
|||
|
|||
$this->config = $this->createMock(IConfig::class); |
|||
$this->urlGenerator = $this->createMock(IURLGenerator::class); |
|||
$this->clientService = $this->createMock(IClientService::class); |
|||
$this->logger = $this->createMock(LoggerInterface::class); |
|||
|
|||
$this->setupcheck = $this->getMockBuilder(OcxProviders::class) |
|||
->onlyMethods(['runHEAD']) |
|||
->setConstructorArgs([ |
|||
$this->l10n, |
|||
$this->config, |
|||
$this->urlGenerator, |
|||
$this->clientService, |
|||
$this->logger, |
|||
]) |
|||
->getMock(); |
|||
} |
|||
|
|||
public function testSuccess(): void { |
|||
$response = $this->createMock(IResponse::class); |
|||
$response->expects($this->any())->method('getStatusCode')->willReturn(200); |
|||
|
|||
$this->setupcheck |
|||
->expects($this->exactly(2)) |
|||
->method('runHEAD') |
|||
->willReturnOnConsecutiveCalls($this->generate([$response]), $this->generate([$response])); |
|||
|
|||
$result = $this->setupcheck->run(); |
|||
$this->assertEquals(SetupResult::SUCCESS, $result->getSeverity()); |
|||
} |
|||
|
|||
public function testLateSuccess(): void { |
|||
$response1 = $this->createMock(IResponse::class); |
|||
$response1->expects($this->exactly(3))->method('getStatusCode')->willReturnOnConsecutiveCalls(404, 500, 200); |
|||
$response2 = $this->createMock(IResponse::class); |
|||
$response2->expects($this->any())->method('getStatusCode')->willReturnOnConsecutiveCalls(200); |
|||
|
|||
$this->setupcheck |
|||
->expects($this->exactly(2)) |
|||
->method('runHEAD') |
|||
->willReturnOnConsecutiveCalls($this->generate([$response1, $response1, $response1]), $this->generate([$response2])); // only one response out of two
|
|||
|
|||
$result = $this->setupcheck->run(); |
|||
$this->assertEquals(SetupResult::SUCCESS, $result->getSeverity()); |
|||
} |
|||
|
|||
public function testNoResponse(): void { |
|||
$response = $this->createMock(IResponse::class); |
|||
$response->expects($this->any())->method('getStatusCode')->willReturn(200); |
|||
|
|||
$this->setupcheck |
|||
->expects($this->exactly(2)) |
|||
->method('runHEAD') |
|||
->willReturnOnConsecutiveCalls($this->generate([]), $this->generate([])); // No responses
|
|||
|
|||
$result = $this->setupcheck->run(); |
|||
$this->assertEquals(SetupResult::WARNING, $result->getSeverity()); |
|||
$this->assertMatchesRegularExpression('/^Could not check/', $result->getDescription()); |
|||
} |
|||
|
|||
public function testPartialResponse(): void { |
|||
$response = $this->createMock(IResponse::class); |
|||
$response->expects($this->any())->method('getStatusCode')->willReturn(200); |
|||
|
|||
$this->setupcheck |
|||
->expects($this->exactly(2)) |
|||
->method('runHEAD') |
|||
->willReturnOnConsecutiveCalls($this->generate([$response]), $this->generate([])); // only one response out of two
|
|||
|
|||
$result = $this->setupcheck->run(); |
|||
$this->assertEquals(SetupResult::WARNING, $result->getSeverity()); |
|||
$this->assertMatchesRegularExpression('/^Could not check/', $result->getDescription()); |
|||
} |
|||
|
|||
public function testInvalidResponse(): void { |
|||
$response = $this->createMock(IResponse::class); |
|||
$response->expects($this->any())->method('getStatusCode')->willReturn(404); |
|||
|
|||
$this->setupcheck |
|||
->expects($this->exactly(2)) |
|||
->method('runHEAD') |
|||
->willReturnOnConsecutiveCalls($this->generate([$response]), $this->generate([$response])); // only one response out of two
|
|||
|
|||
$result = $this->setupcheck->run(); |
|||
$this->assertEquals(SetupResult::WARNING, $result->getSeverity()); |
|||
$this->assertMatchesRegularExpression('/^Your web server is not properly set up/', $result->getDescription()); |
|||
} |
|||
|
|||
public function testPartialInvalidResponse(): void { |
|||
$response1 = $this->createMock(IResponse::class); |
|||
$response1->expects($this->any())->method('getStatusCode')->willReturnOnConsecutiveCalls(200); |
|||
$response2 = $this->createMock(IResponse::class); |
|||
$response2->expects($this->any())->method('getStatusCode')->willReturnOnConsecutiveCalls(404); |
|||
|
|||
$this->setupcheck |
|||
->expects($this->exactly(2)) |
|||
->method('runHEAD') |
|||
->willReturnOnConsecutiveCalls($this->generate([$response1]), $this->generate([$response2])); |
|||
|
|||
$result = $this->setupcheck->run(); |
|||
$this->assertEquals(SetupResult::WARNING, $result->getSeverity()); |
|||
$this->assertMatchesRegularExpression('/^Your web server is not properly set up/', $result->getDescription()); |
|||
} |
|||
|
|||
/** |
|||
* Helper function creates a nicer interface for mocking Generator behavior |
|||
*/ |
|||
protected function generate(array $yield_values) { |
|||
return $this->returnCallback(function () use ($yield_values) { |
|||
yield from $yield_values; |
|||
}); |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue