true, ])), ]); $validator = new TurnstileValidator($httpClient, new NullLogger(), self::SECRET_KEY); $result = $validator->validate('valid-token', '192.168.1.1'); self::assertTrue($result->isValid); self::assertNull($result->errorMessage); } #[Test] public function invalidTokenReturnsInvalid(): void { $httpClient = new MockHttpClient([ new MockResponse(json_encode([ 'success' => false, 'error-codes' => ['invalid-input-response'], ])), ]); $validator = new TurnstileValidator($httpClient, new NullLogger(), self::SECRET_KEY); $result = $validator->validate('invalid-token', '192.168.1.1'); self::assertFalse($result->isValid); self::assertSame('Token invalide ou expiré', $result->errorMessage); } #[Test] public function expiredTokenReturnsInvalid(): void { $httpClient = new MockHttpClient([ new MockResponse(json_encode([ 'success' => false, 'error-codes' => ['timeout-or-duplicate'], ])), ]); $validator = new TurnstileValidator($httpClient, new NullLogger(), self::SECRET_KEY); $result = $validator->validate('expired-token', '192.168.1.1'); self::assertFalse($result->isValid); self::assertSame('Token expiré ou déjà utilisé', $result->errorMessage); } #[Test] public function emptyTokenReturnsInvalid(): void { $httpClient = new MockHttpClient(); // No request should be made $validator = new TurnstileValidator($httpClient, new NullLogger(), self::SECRET_KEY); $result = $validator->validate('', '192.168.1.1'); self::assertFalse($result->isValid); self::assertSame('Token vide', $result->errorMessage); } #[Test] public function apiErrorReturnsValidWhenFailOpenEnabled(): void { // Simulate API error with fail open $httpClient = new MockHttpClient([ new MockResponse('', ['http_code' => 500]), ]); $validator = new TurnstileValidator($httpClient, new NullLogger(), self::SECRET_KEY, failOpen: true); $result = $validator->validate('some-token', '192.168.1.1'); // Fail open - allow through on API errors self::assertTrue($result->isValid); } #[Test] public function apiErrorReturnsInvalidWhenFailOpenDisabled(): void { // Simulate API error with fail closed (production default) $httpClient = new MockHttpClient([ new MockResponse('', ['http_code' => 500]), ]); $validator = new TurnstileValidator($httpClient, new NullLogger(), self::SECRET_KEY, failOpen: false); $result = $validator->validate('some-token', '192.168.1.1'); // Fail closed - block on API errors self::assertFalse($result->isValid); self::assertSame('Service de vérification temporairement indisponible', $result->errorMessage); } #[Test] public function networkErrorReturnsValidWhenFailOpenEnabled(): void { // Simulate network error with fail open $httpClient = new MockHttpClient([ new MockResponse('', ['error' => 'Network error']), ]); $validator = new TurnstileValidator($httpClient, new NullLogger(), self::SECRET_KEY, failOpen: true); $result = $validator->validate('some-token', '192.168.1.1'); // Fail open - allow through on network errors self::assertTrue($result->isValid); } #[Test] public function networkErrorReturnsInvalidWhenFailOpenDisabled(): void { // Simulate network error with fail closed $httpClient = new MockHttpClient([ new MockResponse('', ['error' => 'Network error']), ]); $validator = new TurnstileValidator($httpClient, new NullLogger(), self::SECRET_KEY, failOpen: false); $result = $validator->validate('some-token', '192.168.1.1'); // Fail closed - block on network errors self::assertFalse($result->isValid); } #[Test] public function invalidSecretKeyReturnsInvalid(): void { $httpClient = new MockHttpClient([ new MockResponse(json_encode([ 'success' => false, 'error-codes' => ['invalid-input-secret'], ])), ]); $validator = new TurnstileValidator($httpClient, new NullLogger(), self::SECRET_KEY); $result = $validator->validate('token', '192.168.1.1'); self::assertFalse($result->isValid); self::assertSame('Configuration serveur invalide', $result->errorMessage); } #[Test] public function missingSecretKeyReturnsInvalid(): void { $httpClient = new MockHttpClient([ new MockResponse(json_encode([ 'success' => false, 'error-codes' => ['missing-input-secret'], ])), ]); $validator = new TurnstileValidator($httpClient, new NullLogger(), self::SECRET_KEY); $result = $validator->validate('token', '192.168.1.1'); self::assertFalse($result->isValid); self::assertSame('Configuration serveur invalide', $result->errorMessage); } #[Test] public function unknownErrorCodeReturnsGenericMessage(): void { $httpClient = new MockHttpClient([ new MockResponse(json_encode([ 'success' => false, 'error-codes' => ['unknown-error-code'], ])), ]); $validator = new TurnstileValidator($httpClient, new NullLogger(), self::SECRET_KEY); $result = $validator->validate('token', '192.168.1.1'); self::assertFalse($result->isValid); self::assertSame('Vérification échouée', $result->errorMessage); } #[Test] public function validationWithoutIpWorks(): void { $httpClient = new MockHttpClient([ new MockResponse(json_encode([ 'success' => true, ])), ]); $validator = new TurnstileValidator($httpClient, new NullLogger(), self::SECRET_KEY); $result = $validator->validate('valid-token'); self::assertTrue($result->isValid); } }