searchEngine, ['google', 'bing'], true); } public function search(SerpQuery $q): SerpResponse { $this->guard(); $this->errors(); $results = self::$results ?: [new SerpResultData(1, 'https://example.com/result', 'Example', 'example.com', 'Deterministic test result')]; return new SerpResponse($this->key(), $results, 'fake-reference', $q->limit); } public function submit(SerpQuery $q): SerpSubmission { $this->guard(); $this->errors(); return new SerpSubmission($this->key(), '00000000-0000-0000-0000-000000000001', 0.0, 'USD', 20100); } public function collect(string $taskId, int $limit): SerpTaskResult { $this->guard(); $this->errors(); if (self::$mode === 'waiting') { return SerpTaskResult::waiting(40601); }$response = $this->search(new SerpQuery('fake', 'google', 'TR', 'tr', 'desktop', $limit)); $response = new SerpResponse($this->key(), $response->results, $taskId, $limit); return SerpTaskResult::ready($response, 0.0, 'USD', 20000); } private function guard(): void { if (! (app()->environment('testing') || (app()->environment('local') && config('serp.allow_fake_local')))) { throw new ProviderConfigurationException('Fake provider forbidden.'); } } private function errors(): void { if (self::$mode === 'timeout') { throw new ProviderTimeoutException('secret timeout'); }if (self::$mode === 'rate_limit') { throw new ProviderRateLimitException('secret rate'); }if (self::$mode === 'permanent') { throw new PermanentProviderException('secret permanent'); } } }