From 99ce8f73f969b90e20de682ae9fa10b6fdf67d4a Mon Sep 17 00:00:00 2001 From: "Mark A. Hershberger" Date: Sun, 20 Sep 2026 22:32:20 -0400 Subject: [PATCH] Fix TypeError in deleteState: allow null etag in tryDeleteState deleteStateAsync() passes null as the etag to tryDeleteStateAsync(), whose $etag parameter is typed as non-nullable string, so any call to deleteState() fatals with: TypeError: tryDeleteStateAsync(): Argument #3 ($etag) must be of type string, null given The implementation already handles an empty etag (no If-Match header is sent), so widen the parameter to string|null on both tryDeleteState and tryDeleteStateAsync (abstract + HTTP implementation) and add regression tests for deleting with and without an etag. Signed-off-by: Mark A. Hershberger --- src/lib/Client/DaprClient.php | 8 +++---- src/lib/Client/HttpStateTrait.php | 4 ++-- tests/DeleteStateTest.php | 37 +++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 tests/DeleteStateTest.php diff --git a/src/lib/Client/DaprClient.php b/src/lib/Client/DaprClient.php index f0834dd..5d58d1b 100644 --- a/src/lib/Client/DaprClient.php +++ b/src/lib/Client/DaprClient.php @@ -385,7 +385,7 @@ abstract public function deleteState( /** * @param string $storeName * @param string $key - * @param string $etag + * @param string|null $etag * @param Consistency|null $consistency * @param array $metadata * @return PromiseInterface @@ -393,7 +393,7 @@ abstract public function deleteState( abstract public function tryDeleteStateAsync( string $storeName, string $key, - string $etag, + string|null $etag, Consistency|null $consistency = null, array $metadata = [] ): PromiseInterface; @@ -401,7 +401,7 @@ abstract public function tryDeleteStateAsync( /** * @param string $storeName * @param string $key - * @param string $etag + * @param string|null $etag * @param Consistency|null $consistency * @param array $metadata * @return bool @@ -409,7 +409,7 @@ abstract public function tryDeleteStateAsync( abstract public function tryDeleteState( string $storeName, string $key, - string $etag, + string|null $etag, Consistency|null $consistency = null, array $metadata = [] ): bool; diff --git a/src/lib/Client/HttpStateTrait.php b/src/lib/Client/HttpStateTrait.php index 9243797..2c2e926 100644 --- a/src/lib/Client/HttpStateTrait.php +++ b/src/lib/Client/HttpStateTrait.php @@ -237,7 +237,7 @@ public function deleteStateAsync( public function tryDeleteStateAsync( string $storeName, string $key, - string $etag, + string|null $etag, Consistency|null $consistency = null, array $metadata = [] ): PromiseInterface { @@ -269,7 +269,7 @@ public function tryDeleteStateAsync( public function tryDeleteState( string $storeName, string $key, - string $etag, + string|null $etag, Consistency|null $consistency = null, array $metadata = [] ): bool { diff --git a/tests/DeleteStateTest.php b/tests/DeleteStateTest.php new file mode 100644 index 0000000..b41ff23 --- /dev/null +++ b/tests/DeleteStateTest.php @@ -0,0 +1,37 @@ +get_http_client_stack([new Response(204)]); + $client = $this->get_new_client_with_http($stack->client); + + $client->deleteState(storeName: 'store', key: 'key'); + + $request = $this->get_last_request($stack); + $this->assertRequestMethod('DELETE', $request); + $this->assertRequestUri('/v1.0/state/store/key', $request); + $this->assertFalse($request->hasHeader('If-Match')); + } + + public function testTryDeleteStateWithEtag(): void + { + $stack = $this->get_http_client_stack([new Response(204)]); + $client = $this->get_new_client_with_http($stack->client); + + $client->tryDeleteState(storeName: 'store', key: 'key', etag: 'abc123'); + + $request = $this->get_last_request($stack); + $this->assertRequestMethod('DELETE', $request); + $this->assertRequestUri('/v1.0/state/store/key', $request); + $this->assertRequestHasHeaders(['If-Match' => 'abc123'], $request); + } +}