diff --git a/tests/Unit/Services/MetadataResolverServiceTest.php b/tests/Unit/Services/MetadataResolverServiceTest.php new file mode 100644 index 0000000..d8c7528 --- /dev/null +++ b/tests/Unit/Services/MetadataResolverServiceTest.php @@ -0,0 +1,182 @@ +seed(); + Carbon::setTestNow('2020-07-21 19:19:19'); + } + + protected function tearDown(): void + { + parent::tearDown(); + Carbon::setTestNow(); + } + + public function testOnRuntimeException() + { + $this->mock(MetadataResolver::class, function (MockInterface $mock) { + $mock->shouldReceive('resolve')->andReturnUsing(function ($url) { + throw new \RuntimeException('Something happened!'); + }); + }); + + try { + $service = app()->make(MetadataResolveService::class); + $service->execute('http://example.com'); + } catch (UncaughtResolverException $e) { + $this->assertDatabaseHas('metadata', [ + 'url' => 'http://example.com', + 'error_at' => new Carbon('2020-07-21 19:19:19'), + 'error_count' => 1, + 'error_exception_class' => \RuntimeException::class, + 'error_http_code' => null, + 'error_body' => 'Something happened!', + ]); + + return; + } + $this->fail(); + } + + public function testOnHttpClientError() + { + $handler = HandlerStack::create(new MockHandler([new Response(404)])); + $client = new Client(['handler' => $handler]); + $this->instance(Client::class, $client); + + try { + $service = app()->make(MetadataResolveService::class); + $service->execute('http://example.com'); + } catch (UncaughtResolverException $e) { + $this->assertDatabaseHas('metadata', [ + 'url' => 'http://example.com', + 'error_at' => new Carbon('2020-07-21 19:19:19'), + 'error_count' => 1, + 'error_exception_class' => ClientException::class, + 'error_http_code' => 404, + ]); + + return; + } + $this->fail(); + } + + public function testOnHttpServerError() + { + $handler = HandlerStack::create(new MockHandler([new Response(503), new Response(503)])); + $client = new Client(['handler' => $handler]); + $this->instance(Client::class, $client); + + try { + $service = app()->make(MetadataResolveService::class); + $service->execute('http://example.com'); + } catch (UncaughtResolverException $e) { + $this->assertDatabaseHas('metadata', [ + 'url' => 'http://example.com', + 'error_at' => new Carbon('2020-07-21 19:19:19'), + 'error_count' => 1, + 'error_exception_class' => ServerException::class, + 'error_http_code' => 503, + ]); + + return; + } + $this->fail(); + } + + public function testCircuitBreak() + { + $this->mock(MetadataResolver::class, function (MockInterface $mock) { + $mock->shouldReceive('resolve')->andReturnUsing(function ($url) { + throw new \RuntimeException('Something happened!'); + }); + }); + + try { + for ($i = 0; $i < 6; $i++) { + try { + $service = app()->make(MetadataResolveService::class); + $service->execute('http://example.com'); + } catch (UncaughtResolverException $e) { + } + } + } catch (ResolverCircuitBreakException $e) { + $this->assertDatabaseHas('metadata', [ + 'url' => 'http://example.com', + 'error_at' => new Carbon('2020-07-21 19:19:19'), + 'error_count' => 5, + 'error_exception_class' => \RuntimeException::class, + 'error_http_code' => null, + 'error_body' => 'Something happened!', + ]); + + return; + } + $this->fail(); + } + + public function testOnResurrect() + { + $successBody = << + + + + + + Test Document + + + + +HTML; + $handler = HandlerStack::create(new MockHandler([ + new Response(404), + new Response(200, ['Content-Type' => 'text/html'], $successBody), + ])); + $client = new Client(['handler' => $handler]); + $this->instance(Client::class, $client); + + for ($i = 0; $i < 2; $i++) { + try { + $service = app()->make(MetadataResolveService::class); + $service->execute('http://example.com'); + } catch (UncaughtResolverException $e) { + } + } + + $this->assertDatabaseHas('metadata', [ + 'url' => 'http://example.com', + 'title' => 'OGP Title', + 'description' => 'OGP Description', + 'image' => '', + 'error_at' => null, + 'error_count' => 0, + 'error_exception_class' => null, + 'error_http_code' => null, + 'error_body' => null, + ]); + } +}