diff --git a/.horde.yml b/.horde.yml index 6409ba2..0ecdae7 100644 --- a/.horde.yml +++ b/.horde.yml @@ -38,8 +38,6 @@ dependencies: required: php: ^8.2 composer: - horde/core: ^3 - horde/dav: ^2 horde/exception: ^3 horde/perms: ^3 horde/serialize: ^3 @@ -55,6 +53,8 @@ dependencies: psr/event-dispatcher: ^1.0 optional: composer: + horde/core: ^3 + horde/dav: ^2 horde/http: ^3 horde/activesync: ^3 horde/eventdispatcher: ^3 diff --git a/src/Dispatch/ApiCallContext.php b/src/Dispatch/ApiCallContext.php new file mode 100644 index 0000000..b53dee4 --- /dev/null +++ b/src/Dispatch/ApiCallContext.php @@ -0,0 +1,47 @@ + $attributes + */ + public function __construct( + private array $attributes = [], + ) {} + + public function getAttribute(string $name, mixed $default = null): mixed + { + return $this->attributes[$name] ?? $default; + } + + public function withAttribute(string $name, mixed $value): self + { + return new self(array_merge($this->attributes, [$name => $value])); + } + + /** + * @return array + */ + public function getAttributes(): array + { + return $this->attributes; + } +} diff --git a/src/Dispatch/ApiProviderInterface.php b/src/Dispatch/ApiProviderInterface.php new file mode 100644 index 0000000..dd0d5d8 --- /dev/null +++ b/src/Dispatch/ApiProviderInterface.php @@ -0,0 +1,49 @@ + + */ + public function listMethods(?ApiCallContext $context = null): array; +} diff --git a/src/JsonRpc/Dispatch/CallableMapProvider.php b/src/Dispatch/CallableMapProvider.php similarity index 75% rename from src/JsonRpc/Dispatch/CallableMapProvider.php rename to src/Dispatch/CallableMapProvider.php index d848968..71ce8e5 100644 --- a/src/JsonRpc/Dispatch/CallableMapProvider.php +++ b/src/Dispatch/CallableMapProvider.php @@ -9,12 +9,12 @@ * did not receive this file, see http://www.horde.org/licenses/lgpl21. */ -namespace Horde\Rpc\JsonRpc\Dispatch; +namespace Horde\Rpc\Dispatch; /** * Generic provider backed by a callable map. * - * Each method is a name→callable pair. Implements both ApiProviderInterface + * Each method is a name-callable pair. Implements both ApiProviderInterface * (method registry) and MethodInvokerInterface (method execution), making it * a convenient all-in-one for simple APIs. * @@ -34,7 +34,7 @@ final class CallableMapProvider implements ApiProviderInterface, MethodInvokerIn private readonly array $descriptors; /** - * @param array $methods Name→callable map + * @param array $methods Name-callable map * @param array $descriptors Optional descriptors keyed by method name. * Methods without an explicit descriptor get a minimal auto-generated one. */ @@ -49,22 +49,22 @@ public function __construct(array $methods, array $descriptors = []) $this->descriptors = $merged; } - public function hasMethod(string $method): bool + public function hasMethod(string $method, ?ApiCallContext $context = null): bool { return isset($this->methods[$method]); } - public function getMethodDescriptor(string $method): ?MethodDescriptor + public function getMethodDescriptor(string $method, ?ApiCallContext $context = null): ?MethodDescriptor { return $this->descriptors[$method] ?? null; } - public function listMethods(): array + public function listMethods(?ApiCallContext $context = null): array { return array_values($this->descriptors); } - public function invoke(string $method, array $params): Result + public function invoke(string $method, array $params, ?ApiCallContext $context = null): Result { return new Result(($this->methods[$method])(...$params)); } diff --git a/src/JsonRpc/Dispatch/MethodDescriptor.php b/src/Dispatch/MethodDescriptor.php similarity index 92% rename from src/JsonRpc/Dispatch/MethodDescriptor.php rename to src/Dispatch/MethodDescriptor.php index 0f2941b..b27d57d 100644 --- a/src/JsonRpc/Dispatch/MethodDescriptor.php +++ b/src/Dispatch/MethodDescriptor.php @@ -9,10 +9,10 @@ * did not receive this file, see http://www.horde.org/licenses/lgpl21. */ -namespace Horde\Rpc\JsonRpc\Dispatch; +namespace Horde\Rpc\Dispatch; /** - * Metadata describing an available JSON-RPC method. + * Metadata describing an available API method. */ final readonly class MethodDescriptor { diff --git a/src/JsonRpc/Dispatch/MethodInvokerInterface.php b/src/Dispatch/MethodInvokerInterface.php similarity index 81% rename from src/JsonRpc/Dispatch/MethodInvokerInterface.php rename to src/Dispatch/MethodInvokerInterface.php index b2c1fa2..5f62228 100644 --- a/src/JsonRpc/Dispatch/MethodInvokerInterface.php +++ b/src/Dispatch/MethodInvokerInterface.php @@ -9,7 +9,7 @@ * did not receive this file, see http://www.horde.org/licenses/lgpl21. */ -namespace Horde\Rpc\JsonRpc\Dispatch; +namespace Horde\Rpc\Dispatch; /** * Executes a method by name with given parameters. @@ -22,5 +22,5 @@ interface MethodInvokerInterface /** * Invoke a method by name with the given parameters. */ - public function invoke(string $method, array $params): Result; + public function invoke(string $method, array $params, ?ApiCallContext $context = null): Result; } diff --git a/src/JsonRpc/Dispatch/Result.php b/src/Dispatch/Result.php similarity index 91% rename from src/JsonRpc/Dispatch/Result.php rename to src/Dispatch/Result.php index d4185a1..36bb882 100644 --- a/src/JsonRpc/Dispatch/Result.php +++ b/src/Dispatch/Result.php @@ -9,7 +9,7 @@ * did not receive this file, see http://www.horde.org/licenses/lgpl21. */ -namespace Horde\Rpc\JsonRpc\Dispatch; +namespace Horde\Rpc\Dispatch; /** * The outcome of a dispatched method invocation. diff --git a/src/JsonRpc/Dispatch/ApiProviderInterface.php b/src/JsonRpc/Dispatch/ApiProviderInterface.php deleted file mode 100644 index 23c3d22..0000000 --- a/src/JsonRpc/Dispatch/ApiProviderInterface.php +++ /dev/null @@ -1,41 +0,0 @@ - - */ - public function listMethods(): array; -} diff --git a/src/JsonRpc/Dispatch/Dispatcher.php b/src/JsonRpc/Dispatch/Dispatcher.php index c26a63f..eb0bf33 100644 --- a/src/JsonRpc/Dispatch/Dispatcher.php +++ b/src/JsonRpc/Dispatch/Dispatcher.php @@ -11,6 +11,9 @@ namespace Horde\Rpc\JsonRpc\Dispatch; +use Horde\Rpc\Dispatch\ApiProviderInterface; +use Horde\Rpc\Dispatch\MethodInvokerInterface; +use Horde\Rpc\Dispatch\Result; use Horde\Rpc\JsonRpc\Exception\MethodNotFoundException; use Horde\Rpc\JsonRpc\Protocol\Request; diff --git a/src/JsonRpc/Dispatch/DispatcherInterface.php b/src/JsonRpc/Dispatch/DispatcherInterface.php index fa6768d..f4e125e 100644 --- a/src/JsonRpc/Dispatch/DispatcherInterface.php +++ b/src/JsonRpc/Dispatch/DispatcherInterface.php @@ -11,6 +11,7 @@ namespace Horde\Rpc\JsonRpc\Dispatch; +use Horde\Rpc\Dispatch\Result; use Horde\Rpc\JsonRpc\Protocol\Request; /** diff --git a/src/JsonRpc/Dispatch/HordeRegistryApiProvider.php b/src/JsonRpc/Dispatch/HordeRegistryApiProvider.php index 2040761..19273aa 100644 --- a/src/JsonRpc/Dispatch/HordeRegistryApiProvider.php +++ b/src/JsonRpc/Dispatch/HordeRegistryApiProvider.php @@ -13,6 +13,11 @@ use Horde_Exception; use Horde_Registry; +use Horde\Rpc\Dispatch\ApiCallContext; +use Horde\Rpc\Dispatch\ApiProviderInterface; +use Horde\Rpc\Dispatch\MethodDescriptor; +use Horde\Rpc\Dispatch\MethodInvokerInterface; +use Horde\Rpc\Dispatch\Result; use Horde\Rpc\JsonRpc\Exception\InternalErrorException; use Horde\Rpc\JsonRpc\Exception\MethodNotFoundException; @@ -34,12 +39,12 @@ public function __construct( private readonly Horde_Registry $registry, ) {} - public function hasMethod(string $method): bool + public function hasMethod(string $method, ?ApiCallContext $context = null): bool { return (bool) $this->registry->hasMethod($this->dotToSlash($method)); } - public function getMethodDescriptor(string $method): ?MethodDescriptor + public function getMethodDescriptor(string $method, ?ApiCallContext $context = null): ?MethodDescriptor { if (!$this->hasMethod($method)) { return null; @@ -48,7 +53,7 @@ public function getMethodDescriptor(string $method): ?MethodDescriptor return new MethodDescriptor($method); } - public function listMethods(): array + public function listMethods(?ApiCallContext $context = null): array { $descriptors = []; foreach ($this->registry->listMethods() as $slashMethod) { @@ -59,7 +64,7 @@ public function listMethods(): array return $descriptors; } - public function invoke(string $method, array $params): Result + public function invoke(string $method, array $params, ?ApiCallContext $context = null): Result { $slashMethod = $this->dotToSlash($method); diff --git a/src/JsonRpc/Dispatch/MathApiProvider.php b/src/JsonRpc/Dispatch/MathApiProvider.php index 6df5901..9fc9eda 100644 --- a/src/JsonRpc/Dispatch/MathApiProvider.php +++ b/src/JsonRpc/Dispatch/MathApiProvider.php @@ -11,6 +11,12 @@ namespace Horde\Rpc\JsonRpc\Dispatch; +use Horde\Rpc\Dispatch\ApiCallContext; +use Horde\Rpc\Dispatch\ApiProviderInterface; +use Horde\Rpc\Dispatch\CallableMapProvider; +use Horde\Rpc\Dispatch\MethodDescriptor; +use Horde\Rpc\Dispatch\MethodInvokerInterface; +use Horde\Rpc\Dispatch\Result; use Horde\Rpc\JsonRpc\Exception\InvalidParamsException; /** @@ -121,22 +127,22 @@ public static function create(): self return new self(); } - public function hasMethod(string $method): bool + public function hasMethod(string $method, ?ApiCallContext $context = null): bool { return $this->inner->hasMethod($method); } - public function getMethodDescriptor(string $method): ?MethodDescriptor + public function getMethodDescriptor(string $method, ?ApiCallContext $context = null): ?MethodDescriptor { return $this->inner->getMethodDescriptor($method); } - public function listMethods(): array + public function listMethods(?ApiCallContext $context = null): array { return $this->inner->listMethods(); } - public function invoke(string $method, array $params): Result + public function invoke(string $method, array $params, ?ApiCallContext $context = null): Result { return $this->inner->invoke($method, $params); } diff --git a/src/JsonRpc/JsonRpcHandler.php b/src/JsonRpc/JsonRpcHandler.php index dc3266e..b529bb2 100644 --- a/src/JsonRpc/JsonRpcHandler.php +++ b/src/JsonRpc/JsonRpcHandler.php @@ -11,9 +11,9 @@ namespace Horde\Rpc\JsonRpc; -use Horde\Rpc\JsonRpc\Dispatch\ApiProviderInterface; +use Horde\Rpc\Dispatch\ApiProviderInterface; +use Horde\Rpc\Dispatch\MethodInvokerInterface; use Horde\Rpc\JsonRpc\Dispatch\Dispatcher; -use Horde\Rpc\JsonRpc\Dispatch\MethodInvokerInterface; use Horde\Rpc\JsonRpc\Protocol\Codec; use Horde\Rpc\JsonRpc\Transport\HttpHandler; use Psr\EventDispatcher\EventDispatcherInterface; diff --git a/src/JsonRpc/Transport/HttpHandler.php b/src/JsonRpc/Transport/HttpHandler.php index 8770fac..7a16dd1 100644 --- a/src/JsonRpc/Transport/HttpHandler.php +++ b/src/JsonRpc/Transport/HttpHandler.php @@ -11,8 +11,8 @@ namespace Horde\Rpc\JsonRpc\Transport; +use Horde\Rpc\Dispatch\Result; use Horde\Rpc\JsonRpc\Dispatch\DispatcherInterface; -use Horde\Rpc\JsonRpc\Dispatch\Result; use Horde\Rpc\JsonRpc\Event\BatchProcessing; use Horde\Rpc\JsonRpc\Event\ErrorOccurred; use Horde\Rpc\JsonRpc\Event\NotificationReceived; diff --git a/src/Mcp/McpRouter.php b/src/Mcp/McpRouter.php index 641187e..0387f0b 100644 --- a/src/Mcp/McpRouter.php +++ b/src/Mcp/McpRouter.php @@ -11,8 +11,8 @@ namespace Horde\Rpc\Mcp; -use Horde\Rpc\JsonRpc\Dispatch\ApiProviderInterface; -use Horde\Rpc\JsonRpc\Dispatch\MethodInvokerInterface; +use Horde\Rpc\Dispatch\ApiProviderInterface; +use Horde\Rpc\Dispatch\MethodInvokerInterface; use Horde\Rpc\Mcp\Protocol\ServerCapabilities; use Horde\Rpc\Mcp\Protocol\ServerInfo; use Horde\Rpc\Mcp\Protocol\ToolDescriptor; diff --git a/src/Mcp/McpServer.php b/src/Mcp/McpServer.php index 54f518a..3ea5291 100644 --- a/src/Mcp/McpServer.php +++ b/src/Mcp/McpServer.php @@ -11,8 +11,8 @@ namespace Horde\Rpc\Mcp; -use Horde\Rpc\JsonRpc\Dispatch\ApiProviderInterface; -use Horde\Rpc\JsonRpc\Dispatch\MethodInvokerInterface; +use Horde\Rpc\Dispatch\ApiProviderInterface; +use Horde\Rpc\Dispatch\MethodInvokerInterface; use Horde\Rpc\Mcp\Protocol\ServerCapabilities; use Horde\Rpc\Mcp\Protocol\ServerInfo; use Horde\Rpc\Mcp\Transport\HttpHandler; diff --git a/src/Mcp/Protocol/ToolDescriptor.php b/src/Mcp/Protocol/ToolDescriptor.php index b598985..47afd25 100644 --- a/src/Mcp/Protocol/ToolDescriptor.php +++ b/src/Mcp/Protocol/ToolDescriptor.php @@ -11,7 +11,7 @@ namespace Horde\Rpc\Mcp\Protocol; -use Horde\Rpc\JsonRpc\Dispatch\MethodDescriptor; +use Horde\Rpc\Dispatch\MethodDescriptor; /** * MCP tool descriptor, bridges from MethodDescriptor to MCP tool format. diff --git a/src/Soap/SoapCallHandler.php b/src/Soap/SoapCallHandler.php index e6e1ac7..6a6bc72 100644 --- a/src/Soap/SoapCallHandler.php +++ b/src/Soap/SoapCallHandler.php @@ -11,8 +11,8 @@ namespace Horde\Rpc\Soap; -use Horde\Rpc\JsonRpc\Dispatch\ApiProviderInterface; -use Horde\Rpc\JsonRpc\Dispatch\MethodInvokerInterface; +use Horde\Rpc\Dispatch\ApiProviderInterface; +use Horde\Rpc\Dispatch\MethodInvokerInterface; use SoapFault; /** diff --git a/src/Soap/SoapHandler.php b/src/Soap/SoapHandler.php index aac7050..4dd4c9f 100644 --- a/src/Soap/SoapHandler.php +++ b/src/Soap/SoapHandler.php @@ -11,8 +11,8 @@ namespace Horde\Rpc\Soap; -use Horde\Rpc\JsonRpc\Dispatch\ApiProviderInterface; -use Horde\Rpc\JsonRpc\Dispatch\MethodInvokerInterface; +use Horde\Rpc\Dispatch\ApiProviderInterface; +use Horde\Rpc\Dispatch\MethodInvokerInterface; use Psr\Http\Message\ResponseFactoryInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; diff --git a/test/Unit/ActiveSyncTest.php b/test/Integration/ActiveSyncTest.php similarity index 98% rename from test/Unit/ActiveSyncTest.php rename to test/Integration/ActiveSyncTest.php index 1d5c8cc..8363381 100644 --- a/test/Unit/ActiveSyncTest.php +++ b/test/Integration/ActiveSyncTest.php @@ -9,7 +9,7 @@ * did not receive this file, see http://www.horde.org/licenses/lgpl21. */ -namespace Horde\Rpc\Test\Unit; +namespace Horde\Rpc\Test\Integration; use Horde_ActiveSync; use Horde_Controller_Request_Http; diff --git a/test/Unit/JsonRpc/Dispatch/HordeRegistryApiProviderTest.php b/test/Integration/JsonRpc/Dispatch/HordeRegistryApiProviderTest.php similarity index 98% rename from test/Unit/JsonRpc/Dispatch/HordeRegistryApiProviderTest.php rename to test/Integration/JsonRpc/Dispatch/HordeRegistryApiProviderTest.php index d4f3bc1..72544ea 100644 --- a/test/Unit/JsonRpc/Dispatch/HordeRegistryApiProviderTest.php +++ b/test/Integration/JsonRpc/Dispatch/HordeRegistryApiProviderTest.php @@ -2,12 +2,12 @@ declare(strict_types=1); -namespace Horde\Rpc\Test\Unit\JsonRpc\Dispatch; +namespace Horde\Rpc\Test\Integration\JsonRpc\Dispatch; use Horde_Exception; use Horde_Registry; +use Horde\Rpc\Dispatch\MethodDescriptor; use Horde\Rpc\JsonRpc\Dispatch\HordeRegistryApiProvider; -use Horde\Rpc\JsonRpc\Dispatch\MethodDescriptor; use Horde\Rpc\JsonRpc\Exception\InternalErrorException; use Horde\Rpc\JsonRpc\Exception\MethodNotFoundException; use PHPUnit\Framework\Attributes\CoversClass; diff --git a/test/Unit/Dispatch/ApiCallContextTest.php b/test/Unit/Dispatch/ApiCallContextTest.php new file mode 100644 index 0000000..8d5f048 --- /dev/null +++ b/test/Unit/Dispatch/ApiCallContextTest.php @@ -0,0 +1,73 @@ +assertSame([], $ctx->getAttributes()); + } + + public function testConstructWithAttributes(): void + { + $ctx = new ApiCallContext(['protocol' => 'jsonrpc', 'version' => '2.0']); + $this->assertSame('jsonrpc', $ctx->getAttribute('protocol')); + $this->assertSame('2.0', $ctx->getAttribute('version')); + } + + public function testGetAttributeDefault(): void + { + $ctx = new ApiCallContext(); + $this->assertNull($ctx->getAttribute('missing')); + $this->assertSame('fallback', $ctx->getAttribute('missing', 'fallback')); + } + + public function testWithAttributeReturnsNewInstance(): void + { + $ctx = new ApiCallContext(['a' => 1]); + $ctx2 = $ctx->withAttribute('b', 2); + + $this->assertNotSame($ctx, $ctx2); + $this->assertNull($ctx->getAttribute('b')); + $this->assertSame(2, $ctx2->getAttribute('b')); + $this->assertSame(1, $ctx2->getAttribute('a')); + } + + public function testWithAttributeOverwritesExisting(): void + { + $ctx = new ApiCallContext(['key' => 'old']); + $ctx2 = $ctx->withAttribute('key', 'new'); + + $this->assertSame('old', $ctx->getAttribute('key')); + $this->assertSame('new', $ctx2->getAttribute('key')); + } + + public function testGetAttributesReturnsAll(): void + { + $attrs = ['protocol' => 'mcp', 'user' => 'admin']; + $ctx = new ApiCallContext($attrs); + $this->assertSame($attrs, $ctx->getAttributes()); + } + + public function testChainedWithAttributes(): void + { + $ctx = (new ApiCallContext()) + ->withAttribute('protocol', 'soap') + ->withAttribute('user', 'test') + ->withAttribute('authenticated', true); + + $this->assertSame('soap', $ctx->getAttribute('protocol')); + $this->assertSame('test', $ctx->getAttribute('user')); + $this->assertTrue($ctx->getAttribute('authenticated')); + $this->assertCount(3, $ctx->getAttributes()); + } +} diff --git a/test/Unit/JsonRpc/Dispatch/CallableMapProviderTest.php b/test/Unit/Dispatch/CallableMapProviderTest.php similarity index 93% rename from test/Unit/JsonRpc/Dispatch/CallableMapProviderTest.php rename to test/Unit/Dispatch/CallableMapProviderTest.php index 96de333..fc1e6de 100644 --- a/test/Unit/JsonRpc/Dispatch/CallableMapProviderTest.php +++ b/test/Unit/Dispatch/CallableMapProviderTest.php @@ -2,10 +2,10 @@ declare(strict_types=1); -namespace Horde\Rpc\Test\Unit\JsonRpc\Dispatch; +namespace Horde\Rpc\Test\Unit\Dispatch; -use Horde\Rpc\JsonRpc\Dispatch\CallableMapProvider; -use Horde\Rpc\JsonRpc\Dispatch\MethodDescriptor; +use Horde\Rpc\Dispatch\CallableMapProvider; +use Horde\Rpc\Dispatch\MethodDescriptor; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; diff --git a/test/Unit/JsonRpc/Dispatch/MethodDescriptorTest.php b/test/Unit/Dispatch/MethodDescriptorTest.php similarity index 95% rename from test/Unit/JsonRpc/Dispatch/MethodDescriptorTest.php rename to test/Unit/Dispatch/MethodDescriptorTest.php index c64a793..441d051 100644 --- a/test/Unit/JsonRpc/Dispatch/MethodDescriptorTest.php +++ b/test/Unit/Dispatch/MethodDescriptorTest.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace Horde\Rpc\Test\Unit\JsonRpc\Dispatch; +namespace Horde\Rpc\Test\Unit\Dispatch; -use Horde\Rpc\JsonRpc\Dispatch\MethodDescriptor; +use Horde\Rpc\Dispatch\MethodDescriptor; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; diff --git a/test/Unit/JsonRpc/Dispatch/ResultTest.php b/test/Unit/Dispatch/ResultTest.php similarity index 87% rename from test/Unit/JsonRpc/Dispatch/ResultTest.php rename to test/Unit/Dispatch/ResultTest.php index 3b9930f..eb6e144 100644 --- a/test/Unit/JsonRpc/Dispatch/ResultTest.php +++ b/test/Unit/Dispatch/ResultTest.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace Horde\Rpc\Test\Unit\JsonRpc\Dispatch; +namespace Horde\Rpc\Test\Unit\Dispatch; -use Horde\Rpc\JsonRpc\Dispatch\Result; +use Horde\Rpc\Dispatch\Result; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; diff --git a/test/Unit/JsonRpc/Dispatch/DispatcherTest.php b/test/Unit/JsonRpc/Dispatch/DispatcherTest.php index c57513c..34407bf 100644 --- a/test/Unit/JsonRpc/Dispatch/DispatcherTest.php +++ b/test/Unit/JsonRpc/Dispatch/DispatcherTest.php @@ -4,11 +4,12 @@ namespace Horde\Rpc\Test\Unit\JsonRpc\Dispatch; -use Horde\Rpc\JsonRpc\Dispatch\ApiProviderInterface; +use Horde\Rpc\Dispatch\ApiCallContext; +use Horde\Rpc\Dispatch\ApiProviderInterface; +use Horde\Rpc\Dispatch\MethodDescriptor; +use Horde\Rpc\Dispatch\MethodInvokerInterface; +use Horde\Rpc\Dispatch\Result; use Horde\Rpc\JsonRpc\Dispatch\Dispatcher; -use Horde\Rpc\JsonRpc\Dispatch\MethodDescriptor; -use Horde\Rpc\JsonRpc\Dispatch\MethodInvokerInterface; -use Horde\Rpc\JsonRpc\Dispatch\Result; use Horde\Rpc\JsonRpc\Exception\InternalErrorException; use Horde\Rpc\JsonRpc\Exception\InvalidParamsException; use Horde\Rpc\JsonRpc\Exception\MethodNotFoundException; @@ -40,17 +41,17 @@ public function __construct( private readonly array $descriptors, ) {} - public function hasMethod(string $method): bool + public function hasMethod(string $method, ?ApiCallContext $context = null): bool { return isset($this->descriptors[$method]); } - public function getMethodDescriptor(string $method): ?MethodDescriptor + public function getMethodDescriptor(string $method, ?ApiCallContext $context = null): ?MethodDescriptor { return $this->descriptors[$method] ?? null; } - public function listMethods(): array + public function listMethods(?ApiCallContext $context = null): array { return array_values($this->descriptors); } @@ -62,7 +63,7 @@ public function __construct( private readonly array $methods, ) {} - public function invoke(string $method, array $params): Result + public function invoke(string $method, array $params, ?ApiCallContext $context = null): Result { return new Result(($this->methods[$method])(...$params)); } @@ -134,7 +135,7 @@ public function testProviderWinsOverBuiltInDiscover(): void public function testInvokerExceptionPropagates(): void { $invoker = new class implements MethodInvokerInterface { - public function invoke(string $method, array $params): Result + public function invoke(string $method, array $params, ?ApiCallContext $context = null): Result { throw new InvalidParamsException('Bad params'); } @@ -152,7 +153,7 @@ public function invoke(string $method, array $params): Result public function testInvokerInternalErrorPropagates(): void { $invoker = new class implements MethodInvokerInterface { - public function invoke(string $method, array $params): Result + public function invoke(string $method, array $params, ?ApiCallContext $context = null): Result { throw new InternalErrorException('Something broke'); } diff --git a/test/Unit/JsonRpc/Dispatch/MathApiProviderTest.php b/test/Unit/JsonRpc/Dispatch/MathApiProviderTest.php index 45bb277..ca71def 100644 --- a/test/Unit/JsonRpc/Dispatch/MathApiProviderTest.php +++ b/test/Unit/JsonRpc/Dispatch/MathApiProviderTest.php @@ -4,9 +4,9 @@ namespace Horde\Rpc\Test\Unit\JsonRpc\Dispatch; +use Horde\Rpc\Dispatch\MethodDescriptor; use Horde\Rpc\JsonRpc\Dispatch\Dispatcher; use Horde\Rpc\JsonRpc\Dispatch\MathApiProvider; -use Horde\Rpc\JsonRpc\Dispatch\MethodDescriptor; use Horde\Rpc\JsonRpc\Exception\InvalidParamsException; use Horde\Rpc\JsonRpc\Protocol\Codec; use Horde\Rpc\JsonRpc\Protocol\Request; diff --git a/test/Unit/JsonRpc/TestDouble/CallableMapProvider.php b/test/Unit/JsonRpc/TestDouble/CallableMapProvider.php index 227947d..5d889da 100644 --- a/test/Unit/JsonRpc/TestDouble/CallableMapProvider.php +++ b/test/Unit/JsonRpc/TestDouble/CallableMapProvider.php @@ -4,10 +4,11 @@ namespace Horde\Rpc\Test\Unit\JsonRpc\TestDouble; -use Horde\Rpc\JsonRpc\Dispatch\ApiProviderInterface; -use Horde\Rpc\JsonRpc\Dispatch\MethodDescriptor; -use Horde\Rpc\JsonRpc\Dispatch\MethodInvokerInterface; -use Horde\Rpc\JsonRpc\Dispatch\Result; +use Horde\Rpc\Dispatch\ApiCallContext; +use Horde\Rpc\Dispatch\ApiProviderInterface; +use Horde\Rpc\Dispatch\MethodDescriptor; +use Horde\Rpc\Dispatch\MethodInvokerInterface; +use Horde\Rpc\Dispatch\Result; /** * Simple callable-map implementation for testing. @@ -32,22 +33,22 @@ public function __construct(array $methods = []) } } - public function hasMethod(string $method): bool + public function hasMethod(string $method, ?ApiCallContext $context = null): bool { return isset($this->methods[$method]); } - public function getMethodDescriptor(string $method): ?MethodDescriptor + public function getMethodDescriptor(string $method, ?ApiCallContext $context = null): ?MethodDescriptor { return $this->descriptors[$method] ?? null; } - public function listMethods(): array + public function listMethods(?ApiCallContext $context = null): array { return array_values($this->descriptors); } - public function invoke(string $method, array $params): Result + public function invoke(string $method, array $params, ?ApiCallContext $context = null): Result { return new Result(($this->methods[$method])(...$params)); } diff --git a/test/Unit/Mcp/McpRouterTest.php b/test/Unit/Mcp/McpRouterTest.php index 89d9735..644934c 100644 --- a/test/Unit/Mcp/McpRouterTest.php +++ b/test/Unit/Mcp/McpRouterTest.php @@ -4,8 +4,8 @@ namespace Horde\Rpc\Test\Unit\Mcp; -use Horde\Rpc\JsonRpc\Dispatch\CallableMapProvider; -use Horde\Rpc\JsonRpc\Dispatch\MethodDescriptor; +use Horde\Rpc\Dispatch\CallableMapProvider; +use Horde\Rpc\Dispatch\MethodDescriptor; use Horde\Rpc\Mcp\AuthContext; use Horde\Rpc\Mcp\McpError; use Horde\Rpc\Mcp\McpRouter; diff --git a/test/Unit/Mcp/Protocol/ToolDescriptorTest.php b/test/Unit/Mcp/Protocol/ToolDescriptorTest.php index 14f901f..0c54825 100644 --- a/test/Unit/Mcp/Protocol/ToolDescriptorTest.php +++ b/test/Unit/Mcp/Protocol/ToolDescriptorTest.php @@ -4,7 +4,7 @@ namespace Horde\Rpc\Test\Unit\Mcp\Protocol; -use Horde\Rpc\JsonRpc\Dispatch\MethodDescriptor; +use Horde\Rpc\Dispatch\MethodDescriptor; use Horde\Rpc\Mcp\Protocol\ToolDescriptor; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; diff --git a/test/Unit/Mcp/Transport/HttpHandlerTest.php b/test/Unit/Mcp/Transport/HttpHandlerTest.php index 8b1a7a3..eedcc3b 100644 --- a/test/Unit/Mcp/Transport/HttpHandlerTest.php +++ b/test/Unit/Mcp/Transport/HttpHandlerTest.php @@ -8,8 +8,8 @@ use Horde\Http\ServerRequest; use Horde\Http\StreamFactory; use Horde\Http\Uri; -use Horde\Rpc\JsonRpc\Dispatch\CallableMapProvider; -use Horde\Rpc\JsonRpc\Dispatch\MethodDescriptor; +use Horde\Rpc\Dispatch\CallableMapProvider; +use Horde\Rpc\Dispatch\MethodDescriptor; use Horde\Rpc\Mcp\McpRouter; use Horde\Rpc\Mcp\Protocol\ServerCapabilities; use Horde\Rpc\Mcp\Protocol\ServerInfo; diff --git a/test/Unit/Soap/SoapHandlerTest.php b/test/Unit/Soap/SoapHandlerTest.php index afaf022..d48ed45 100644 --- a/test/Unit/Soap/SoapHandlerTest.php +++ b/test/Unit/Soap/SoapHandlerTest.php @@ -8,7 +8,7 @@ use Horde\Http\ServerRequest; use Horde\Http\StreamFactory; use Horde\Http\Uri; -use Horde\Rpc\JsonRpc\Dispatch\CallableMapProvider; +use Horde\Rpc\Dispatch\CallableMapProvider; use Horde\Rpc\Soap\SoapHandler; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\RequiresPhpExtension;