fix: close etappe-0 whole-branch review findings
- Autoloader: add automattic/jetpack-autoloader and load
vendor/autoload_packages.php; require wordpress/mcp-adapter directly (^0.5).
- ServerRegistrar: make the adapter create_server() call and the
OAuthServerRegistrar class_exists() check injectable so createServer()'s
unhook-before-create ordering and the "mcp-oauth absent" branch are unit
tested; add a smoke-test check that booting REST triggers no
_doing_it_wrong().
- mcp-smoke.sh: assert mcp-adapter's default server route 404s, and that the
subscriber role-gate denial actually carries our/the adapter's denial text
(not just any isError/error).
- Guard tests/Integration/mint-token.php and tec-probe.php with
`defined('WP_CLI') && WP_CLI || exit;`; add .gitattributes export-ignore
for tests/docs-superpowers/.superpowers/phpunit/phpcs config.
- Security: add Server/RequestContext, tracking via
rest_request_before_callbacks whether the current REST dispatch is our
OAuth-protected /mcp/mcp-oauth-server route; AbilityRegistrar's
permission_callback now denies (after the role gate) when abilities are
invoked outside that route. Wired in Plugin::boot().
- Minors: single Plugin::VERSION constant used by ServerRegistrar;
IntegrationRegistry caches its computed abilities list; tec-probe.php
checks wp_insert_post's result and cleans up its probe post in a
try/finally.
composer test: 47/47 green. composer lint: clean. Full mcp-smoke.sh run ends
ALL CHECKS PASSED (plus the expected /.well-known WARN).
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:
@@ -146,4 +146,69 @@ final class ServerRegistrarTest extends TestCase
|
||||
|
||||
(new ServerRegistrar($this->registry(), $this->instructions()))->unhookOAuthDefaultServer();
|
||||
}
|
||||
|
||||
public function testUnhookOAuthDefaultServerIsNoOpWhenOAuthPackageIsAbsent(): void
|
||||
{
|
||||
$oauthRegistrar = Mockery::mock(OAuthServerRegistrar::class);
|
||||
$oauthCallback = [$oauthRegistrar, 'register_server'];
|
||||
$hook = new class {
|
||||
/** @var array<int, array<string, array{function: mixed, accepted_args: int}>> */
|
||||
public array $callbacks = [];
|
||||
};
|
||||
$hook->callbacks = [10 => ['oauth-id' => ['function' => $oauthCallback, 'accepted_args' => 0]]];
|
||||
$GLOBALS['wp_filter']['mcp_adapter_init'] = $hook;
|
||||
|
||||
Functions\expect('remove_action')->never();
|
||||
|
||||
// Simulate wp-media/mcp-oauth not being installed via the injectable
|
||||
// classExists probe (class_exists() is a PHP internal and cannot be
|
||||
// stubbed directly through Brain\Monkey/Patchwork).
|
||||
$registrar = new ServerRegistrar(
|
||||
$this->registry(),
|
||||
$this->instructions(),
|
||||
null,
|
||||
null,
|
||||
static fn (): bool => false
|
||||
);
|
||||
|
||||
$registrar->unhookOAuthDefaultServer();
|
||||
}
|
||||
|
||||
public function testCreateServerUnhooksOAuthDefaultServerBeforeCreatingAdapterServer(): void
|
||||
{
|
||||
Functions\when('doing_action')->justReturn(true);
|
||||
Functions\when('is_wp_error')->justReturn(false);
|
||||
|
||||
$oauthRegistrar = Mockery::mock(OAuthServerRegistrar::class);
|
||||
$oauthCallback = [$oauthRegistrar, 'register_server'];
|
||||
$hook = new class {
|
||||
/** @var array<int, array<string, array{function: mixed, accepted_args: int}>> */
|
||||
public array $callbacks = [];
|
||||
};
|
||||
$hook->callbacks = [10 => ['oauth-id' => ['function' => $oauthCallback, 'accepted_args' => 0]]];
|
||||
$GLOBALS['wp_filter']['mcp_adapter_init'] = $hook;
|
||||
|
||||
/** @var list<string> $order */
|
||||
$order = [];
|
||||
Functions\expect('remove_action')
|
||||
->once()
|
||||
->with('mcp_adapter_init', $oauthCallback, 10)
|
||||
->andReturnUsing(static function () use (&$order): void {
|
||||
$order[] = 'unhook';
|
||||
});
|
||||
|
||||
$registrar = new ServerRegistrar(
|
||||
$this->registry(),
|
||||
$this->instructions(),
|
||||
static fn (): bool => true,
|
||||
static function (array $args) use (&$order): bool {
|
||||
$order[] = 'create';
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
$registrar->createServer();
|
||||
|
||||
self::assertSame(['unhook', 'create'], $order, 'unhook must run before the adapter creates the server');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user