seed(); Carbon::setTestNow('2020-07-21 19:19:19'); // FIXME: 今書かれてるテストはresolveのHTTPリクエストのみを考慮しているので、ContentProviderにデータがないとリクエスト回数がずれる factory(ContentProvider::class)->create(); } 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, ]); } }