fix: discovery admin notice fires on cached 'recommended' too, guarded against oauth/permalink early returns
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
@@ -18,23 +18,84 @@ final class AdminNoticesTest extends TestCase
|
||||
Functions\stubTranslationFunctions();
|
||||
}
|
||||
|
||||
private function status(bool $oauth, ?array $discovery, bool $https): ConnectionStatus
|
||||
/**
|
||||
* The array shape WPMedia\MCP\OAuth\Auth\Discovery\HealthCheck::build_result()
|
||||
* stores in its transient for a genuine (not early-return) check — see
|
||||
* vendor/wp-media/mcp-oauth/inc/Auth/Discovery/HealthCheck.php. Its 'critical'
|
||||
* internal classification (the acme-challenge fingerprint) is itself reported
|
||||
* here as 'recommended' (never 'critical') by that class's own downgrade.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function realDiscoveryResult(string $status): array
|
||||
{
|
||||
return [
|
||||
'label' => 'MCP OAuth discovery documents',
|
||||
'status' => $status,
|
||||
'badge' => ['label' => 'Configuration', 'color' => 'blue'],
|
||||
'description' => '<p>The following .well-known discovery document(s) did not respond as expected: '
|
||||
. 'oauth-protected-resource.</p>',
|
||||
'actions' => '<p>Check your error/access logs for the requests to these paths…</p>',
|
||||
'test' => 'wpmedia_mcp_oauth_wellknown_discovery',
|
||||
];
|
||||
}
|
||||
|
||||
private function status(bool $oauth, ?array $discovery, bool $https, bool $permalinksPretty = true): ConnectionStatus
|
||||
{
|
||||
$status = Mockery::mock(ConnectionStatus::class);
|
||||
$status->allows('oauthEnabled')->andReturn($oauth);
|
||||
$status->allows('discovery')->with(false)->andReturn($discovery);
|
||||
$status->allows('https')->andReturn($https);
|
||||
$status->allows('permalinksPretty')->andReturn($permalinksPretty);
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
public function testWarnsAboutDisabledOAuthAndBrokenDiscoveryEverywhere(): void
|
||||
public function testWarnsAboutDisabledOAuth(): void
|
||||
{
|
||||
$messages = (new AdminNotices($this->status(false, ['status' => 'critical'], true)))->messages(false);
|
||||
$messages = (new AdminNotices($this->status(false, null, true)))->messages(false);
|
||||
|
||||
self::assertCount(2, $messages);
|
||||
self::assertCount(1, $messages);
|
||||
self::assertStringContainsString('OAuth-Server ist deaktiviert', $messages[0]);
|
||||
self::assertStringContainsString('/.well-known/', $messages[1]);
|
||||
}
|
||||
|
||||
public function testWarnsWhenTheCachedDiscoveryStatusIsCriticalOrRecommended(): void
|
||||
{
|
||||
foreach (['critical', 'recommended'] as $status) {
|
||||
$messages = (new AdminNotices($this->status(true, $this->realDiscoveryResult($status), true)))
|
||||
->messages(false);
|
||||
|
||||
self::assertCount(1, $messages, "status={$status}");
|
||||
self::assertStringContainsString('/.well-known/', $messages[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public function testGoodCachedDiscoveryNeverWarns(): void
|
||||
{
|
||||
$notices = new AdminNotices($this->status(true, $this->realDiscoveryResult('good'), true));
|
||||
|
||||
self::assertSame([], $notices->messages(false));
|
||||
}
|
||||
|
||||
public function testDoesNotAddASeparateDiscoveryWarningWhenOAuthIsDisabled(): void
|
||||
{
|
||||
// HealthCheck::run_self_check()'s 'disabled' early return always reports status
|
||||
// 'good' and (like the permalink one below) is never persisted to its transient —
|
||||
// but we guard on the live oauthEnabled() state too rather than relying on that
|
||||
// vendor implementation detail. A stale 'critical' result cached from before OAuth
|
||||
// was disabled must not add a second, redundant notice.
|
||||
$notices = new AdminNotices($this->status(false, $this->realDiscoveryResult('critical'), true));
|
||||
|
||||
$messages = $notices->messages(false);
|
||||
self::assertCount(1, $messages);
|
||||
self::assertStringContainsString('OAuth-Server ist deaktiviert', $messages[0]);
|
||||
}
|
||||
|
||||
public function testDoesNotWarnAboutDiscoveryWithoutPrettyPermalinks(): void
|
||||
{
|
||||
$notices = new AdminNotices($this->status(true, $this->realDiscoveryResult('recommended'), true, false));
|
||||
|
||||
self::assertSame([], $notices->messages(false));
|
||||
}
|
||||
|
||||
public function testHttpsHintOnlyOnTheSettingsPage(): void
|
||||
|
||||
@@ -11,6 +11,12 @@ use Mockery;
|
||||
|
||||
final class ConnectionStatusTest extends TestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
Functions\stubTranslationFunctions();
|
||||
}
|
||||
|
||||
public function testEndpointCheckExpects401WithBearerChallengeAndCachesIt(): void
|
||||
{
|
||||
Functions\when('get_transient')->justReturn(false);
|
||||
@@ -56,4 +62,13 @@ final class ConnectionStatusTest extends TestCase
|
||||
self::assertNull($byLabel['Discovery (/.well-known/)']['ok']);
|
||||
self::assertNull($byLabel['Endpunkt ohne Token']['ok']);
|
||||
}
|
||||
|
||||
public function testPermalinksPrettyReflectsThePermalinkStructureOption(): void
|
||||
{
|
||||
Functions\when('get_option')->justReturn('/%postname%/');
|
||||
self::assertTrue((new ConnectionStatus())->permalinksPretty());
|
||||
|
||||
Functions\when('get_option')->justReturn('');
|
||||
self::assertFalse((new ConnectionStatus())->permalinksPretty());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user