igdb = $this->createMock(IGDBCoverScraper::class); $this->tgdb = $this->createMock(TGDBCoverScraper::class); $this->service = new ScraperService($this->igdb, $this->tgdb); } #[Test] public function it_searches_with_igdb_first(): void { $console = Console::factory()->create(['igdb_platform_id' => 21]); $expected = collect([['title' => 'Game']]); $this->igdb->expects($this->once()) ->method('search') ->with('mario', 21) ->willReturn($expected); $results = $this->service->search('mario', $console->slug); $this->assertEquals($expected, $results); } #[Test] public function it_falls_back_to_tgdb_when_igdb_returns_empty(): void { $console = Console::factory()->create([ 'igdb_platform_id' => 21, 'tgdb_platform_id' => 42, ]); $expected = collect([['title' => 'Game']]); $this->igdb->expects($this->once()) ->method('search') ->willReturn(collect()); $this->tgdb->expects($this->once()) ->method('search') ->with('mario', 42) ->willReturn($expected); $results = $this->service->search('mario', $console->slug); $this->assertEquals($expected, $results); } #[Test] public function it_searches_without_console(): void { $expected = collect([['title' => 'Game']]); $this->igdb->expects($this->once()) ->method('search') ->with('mario', null) ->willReturn($expected); $results = $this->service->search('mario'); $this->assertEquals($expected, $results); } #[Test] public function it_scrapes_cover_for_game_with_igdb_id(): void { $game = Game::factory()->create(['igdb_id' => 123, 'tgdb_id' => null]); $game->load('console'); $this->igdb->expects($this->once()) ->method('getCoverUrl') ->with(123) ->willReturn('https://example.com/cover.jpg'); $this->tgdb->expects($this->never()) ->method('getCoverUrl'); Http::fake([ 'https://example.com/cover.jpg' => Http::response('image-data'), ]); Storage::fake('local'); $result = $this->service->scrapeForGame($game); $this->assertNotNull($result); } #[Test] public function it_falls_back_to_tgdb_for_cover(): void { $game = Game::factory()->create(['igdb_id' => 123, 'tgdb_id' => 456]); $game->load('console'); $this->igdb->expects($this->once()) ->method('getCoverUrl') ->with(123) ->willReturn(null); $this->tgdb->expects($this->once()) ->method('getCoverUrl') ->with(456) ->willReturn('https://example.com/tgdb-cover.jpg'); Http::fake([ 'https://example.com/tgdb-cover.jpg' => Http::response('image-data'), ]); Storage::fake('local'); $result = $this->service->scrapeForGame($game); $this->assertNotNull($result); } #[Test] public function it_returns_null_when_no_cover_found(): void { $game = Game::factory()->create(['igdb_id' => 123, 'tgdb_id' => null]); $game->load('console'); $this->igdb->expects($this->once()) ->method('getCoverUrl') ->willReturn(null); $this->tgdb->expects($this->never()) ->method('getCoverUrl'); $result = $this->service->scrapeForGame($game); $this->assertNull($result); } #[Test] public function it_downloads_cover(): void { $game = Game::factory()->create(['slug' => 'super-mario']); $game->setRelation('console', Console::factory()->create(['slug' => 'nes'])); Http::fake([ 'https://example.com/cover.jpg' => Http::response('image-data'), ]); Storage::fake('local'); $path = $this->service->downloadCover('https://example.com/cover.jpg', $game); $this->assertEquals('covers/nes/super-mario-cover.jpg', $path); Storage::disk('local')->assertExists('covers/nes/super-mario-cover.jpg'); } #[Test] public function it_returns_empty_string_on_download_failure(): void { $game = Game::factory()->create(['slug' => 'super-mario']); $game->setRelation('console', Console::factory()->create(['slug' => 'nes'])); Http::fake([ 'https://example.com/cover.jpg' => fn () => throw new \Exception('Network error'), ]); Storage::fake('local'); $path = $this->service->downloadCover('https://example.com/cover.jpg', $game); $this->assertEquals('', $path); } #[Test] public function it_downloads_cover_with_unknown_console(): void { $game = Game::factory()->create(['slug' => 'test-game']); $game->setRelation('console', null); Http::fake([ 'https://example.com/cover.jpg' => Http::response('image-data'), ]); Storage::fake('local'); $path = $this->service->downloadCover('https://example.com/cover.jpg', $game); $this->assertEquals('covers/unknown/test-game-cover.jpg', $path); } }