Skip to content

Commit

Permalink
response: object to array move strict mode. default: decode http re…
Browse files Browse the repository at this point in the history
…sponse json
  • Loading branch information
usarise committed Jun 7, 2023
1 parent af6f231 commit 52dcaaf
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 25 deletions.
21 changes: 12 additions & 9 deletions src/Client/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
final class Response extends ResponseBase {
/**
* @param array<int, string> $errorCodes
* @param array<string, mixed> $jsonDecode
*/
public function __construct(
public readonly bool $success,
Expand All @@ -17,46 +18,47 @@ public function __construct(
public readonly ?string $hostname = null,
public readonly ?string $action = null,
public readonly ?string $cdata = null,
protected readonly array $jsonDecode = [],
protected readonly string $httpBody = '',
) {
}

public static function decode(string $httpResponse): static {
try {
$dataResponse = json_decode(
$jsonDecode = json_decode(
json: $httpResponse,
associative: true,
flags: JSON_PRESERVE_ZERO_FRACTION | JSON_THROW_ON_ERROR,
);

if (!$dataResponse) {
if (!$jsonDecode) {
return new self(
success: false,
errorCodes: [ErrorCode::UNKNOWN_ERROR],
httpBody: $httpResponse,
);
}

if (!\is_array($dataResponse)) {
if (!\is_array($jsonDecode)) {
return new self(
success: false,
errorCodes: [ErrorCode::UNKNOWN_ERROR],
httpBody: $httpResponse,
);
}

$success = $dataResponse['success'] ?? false;
$errorCodes = $dataResponse['error-codes'] ?? [];
$success = $jsonDecode['success'] ?? false;
$errorCodes = $jsonDecode['error-codes'] ?? [];

if ($success === false && $errorCodes === []) {
$errorCodes[] = ErrorCode::UNKNOWN_ERROR;
}

$challengeTs = $dataResponse['challenge_ts'] ?? null;
$hostname = $dataResponse['hostname'] ?? null;
$challengeTs = $jsonDecode['challenge_ts'] ?? null;
$hostname = $jsonDecode['hostname'] ?? null;

$action = $dataResponse['action'] ?? null;
$cdata = $dataResponse['cdata'] ?? null;
$action = $jsonDecode['action'] ?? null;
$cdata = $jsonDecode['cdata'] ?? null;

return new self(
$success,
Expand All @@ -65,6 +67,7 @@ public static function decode(string $httpResponse): static {
$hostname,
$action,
$cdata,
$jsonDecode,
$httpResponse,
);
} catch (\JsonException) {
Expand Down
17 changes: 12 additions & 5 deletions src/Client/ResponseBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
namespace Turnstile\Client;

abstract class ResponseBase implements \Stringable {
/**
* @param array<string, mixed> $jsonDecode
*/
public function __construct(
protected readonly array $jsonDecode = [],
protected readonly string $httpBody = '',
) {
}
Expand All @@ -15,11 +19,14 @@ abstract public static function decode(string $httpResponse): static;
/**
* @return array<string, mixed>
*/
final public function toArray(): array {
return \array_slice(
array: get_object_vars($this),
offset: 1,
);
final public function toArray(bool $strict = false): array {
return match ($strict) {
true => \array_slice(
array: get_object_vars($this),
offset: 2,
),
default => $this->jsonDecode,
};
}

final public function __toString(): string {
Expand Down
7 changes: 5 additions & 2 deletions src/Turnstile.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,13 @@ private function extendVerify(Response $response): Response {
...$errorCodes,
],
...\array_slice(
array: $response->toArray(),
array: $response->toArray(true),
offset: 2,
),
...[(string) $response],
...[

Check failure on line 87 in src/Turnstile.php

View workflow job for this annotation

GitHub Actions / static-analysis (8.2)

Parameter #4 $hostname of class Turnstile\Client\Response constructor expects string|null, array<string, mixed> given.
$response->toArray(),
(string) $response,
],
);
}

Expand Down
56 changes: 49 additions & 7 deletions tests/Client/ResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function testDecodeSimple(): void {
'action' => null,
'cdata' => null,
],
$responseDecode->toArray(),
$responseDecode->toArray(true),
);
$this->assertEquals(
'{"success": true}',
Expand Down Expand Up @@ -76,15 +76,15 @@ public function testDecodeFull(): void {
'action' => 'login',
'cdata' => 'sessionid-123456789',
],
$responseDecode->toArray(),
$responseDecode->toArray(true),
);
$this->assertEquals(
$httpResponse,
(string) $responseDecode,
);
}

public function testToArray(): void {
public function testToArraySuccessTrue(): void {
$response = new Response(true, []);

$this->assertEquals(
Expand All @@ -96,9 +96,16 @@ public function testToArray(): void {
'action' => null,
'cdata' => null,
],
$response->toArray(true),
);

$this->assertEquals(
[],
$response->toArray(),
);
}

public function testToArraySuccessFalse(): void {
$response = new Response(
success: false,
errorCodes: ['test-error'],
Expand All @@ -113,8 +120,43 @@ public function testToArray(): void {
'action' => null,
'cdata' => null,
],
$response->toArray(true),
);

$this->assertEquals(
[],
$response->toArray(),
);
}

public function testToArrayJsonDecode(): void {
$response = new Response(
success: true,
errorCodes: [],
jsonDecode: ['test' => 'jsonDecode'],
);

$this->assertEquals(
[
'success' => true,
'errorCodes' => [],
'challengeTs' => null,
'hostname' => null,
'action' => null,
'cdata' => null,
],
$response->toArray(true),
);

$this->assertEquals(
['test' => 'jsonDecode'],
$response->toArray(),
);

$this->assertEquals(
['test' => 'jsonDecode'],
$response->toArray(false),
);
}

public function testToString(): void {
Expand Down Expand Up @@ -155,7 +197,7 @@ public function testDecodeUnknownErrorFalse(): void {
'action' => null,
'cdata' => null,
],
$responseDecode->toArray(),
$responseDecode->toArray(true),
);
$this->assertEquals(
'null',
Expand All @@ -180,7 +222,7 @@ public function testDecodeUnknownErrorNotArray(): void {
'action' => null,
'cdata' => null,
],
$responseDecode->toArray(),
$responseDecode->toArray(true),
);
$this->assertEquals(
'true',
Expand All @@ -205,7 +247,7 @@ public function testDecodeUnknownError(): void {
'action' => null,
'cdata' => null,
],
$responseDecode->toArray(),
$responseDecode->toArray(true),
);
$this->assertEquals(
'{"test": true}',
Expand All @@ -230,7 +272,7 @@ public function testDecodeInvalidJson(): void {
'action' => null,
'cdata' => null,
],
$responseDecode->toArray(),
$responseDecode->toArray(true),
);
$this->assertEquals(
'invalid',
Expand Down
10 changes: 9 additions & 1 deletion tests/TurnstileIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,15 @@ public function testError(): void {
'action' => null,
'cdata' => null,
],
$response->toArray(),
$response->toArray(true),
);
$this->assertEquals(
[
'success' => false,
'error-codes' => ['invalid-input-response'],
'messages' => [],
],
$response->toArray(false),
);
$this->assertEquals(
'{"success":false,"error-codes":["invalid-input-response"],"messages":[]}',
Expand Down
48 changes: 47 additions & 1 deletion tests/TurnstileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ public function testVerify(): void {
'action' => null,
'cdata' => null,
],
$response->toArray(true),
);
$this->assertEquals(
[
'success' => true,
],
$response->toArray(),
);
$this->assertEquals(
Expand Down Expand Up @@ -112,6 +118,12 @@ public function testVerifyIdempotency(): void {
'action' => null,
'cdata' => null,
],
$response->toArray(true),
);
$this->assertEquals(
[
'success' => true,
],
$response->toArray(),
);
$this->assertEquals(
Expand All @@ -138,6 +150,12 @@ public function testVerifyIdempotency(): void {
'action' => null,
'cdata' => null,
],
$response->toArray(true),
);
$this->assertEquals(
[
'success' => true,
],
$response->toArray(),
);
$this->assertEquals(
Expand Down Expand Up @@ -175,6 +193,13 @@ public function testError(): void {
'action' => null,
'cdata' => null,
],
$response->toArray(true),
);
$this->assertEquals(
[
'success' => false,
'error-codes' => ['test-error'],
],
$response->toArray(),
);
$this->assertEquals(
Expand Down Expand Up @@ -405,6 +430,16 @@ public function testBadValidation(): void {
'action' => 'login',
'cdata' => 'sessionid-123456789',
],
$response->toArray(true),
);
$this->assertEquals(
[
'success' => true,
'challenge_ts' => $challengeTs,
'hostname' => 'localhost.test',
'action' => 'login',
'cdata' => 'sessionid-123456789',
],
$response->toArray(),
);
$this->assertEquals(
Expand All @@ -415,7 +450,7 @@ public function testBadValidation(): void {

public function testBadClientValidationAndErrors(): void {
$challengeTs = $this->getChallengeTs('now');
$httpResponse = '{"success": false, "error-codes": ["test-error"], "hostname": "localhost.test", "challenge_ts": "' . $challengeTs . '", "action": "login", "cdata": "sessionid-123456789"}';
$httpResponse = '{"success": false, "error-codes": ["test-error"], "challenge_ts": "' . $challengeTs . '", "hostname": "localhost.test", "action": "login", "cdata": "sessionid-123456789"}';

$response = (new Turnstile(
client: $this->getMockHttpClientReturn(
Expand Down Expand Up @@ -464,6 +499,17 @@ public function testBadClientValidationAndErrors(): void {
'action' => 'login',
'cdata' => 'sessionid-123456789',
],
$response->toArray(true),
);
$this->assertEquals(
[
'success' => false,
'error-codes' => ['test-error'],
'challenge_ts' => $challengeTs,
'hostname' => 'localhost.test',
'action' => 'login',
'cdata' => 'sessionid-123456789',
],
$response->toArray(),
);
$this->assertEquals(
Expand Down

0 comments on commit 52dcaaf

Please sign in to comment.