httpClient = $this->createMock(HttpClientInterface::class); $this->client = new MangadexClient( $this->httpClient, 'client_id', 'client_secret', 'username', 'password' ); } private function mockAuthenticationResponse(): MockObject&ResponseInterface { $authResponse = $this->createMock(ResponseInterface::class); $authResponse->method('toArray')->willReturn([ 'access_token' => 'access_token', 'refresh_token' => 'refresh_token' ]); return $authResponse; } public function testAuthenticateSuccess(): void { $response = $this->mockAuthenticationResponse(); $this->httpClient->expects($this->once()) ->method('request') ->with( 'POST', 'https://auth.mangadex.org/realms/mangadex/protocol/openid-connect/token', $this->callback(function ($options) { return $options['body']['grant_type'] === 'password' && $options['body']['username'] === 'username' && $options['body']['password'] === 'password' && $options['body']['client_id'] === 'client_id' && $options['body']['client_secret'] === 'client_secret'; }) ) ->willReturn($response); $this->client->authenticate(); } public function testAuthenticateFailure(): void { $this->httpClient->method('request') ->willThrowException(new \Exception('Authentication failed')); $this->expectException(MangadexAuthenticationException::class); $this->expectExceptionMessage('Failed to authenticate with Mangadex: Authentication failed'); $this->client->authenticate(); } public function testSearchManga(): void { $expectedResponse = [ 'data' => [ [ 'id' => '123', 'attributes' => [ 'title' => ['en' => 'Test Manga'] ] ] ] ]; $authResponse = $this->mockAuthenticationResponse(); $searchResponse = $this->createMock(ResponseInterface::class); $searchResponse->method('toArray')->willReturn($expectedResponse); $searchResponse->method('getStatusCode')->willReturn(200); $this->httpClient->expects($this->exactly(2)) ->method('request') ->willReturnCallback(function ($method, $url) use ($authResponse, $searchResponse) { if (str_contains($url, 'auth.mangadex.org')) { return $authResponse; } return $searchResponse; }); $result = $this->client->searchManga('test'); $this->assertEquals($expectedResponse, $result); } public function testGetMangaRatings(): void { $expectedResponse = [ 'statistics' => [ '123' => [ 'rating' => ['average' => 4.5] ] ] ]; $authResponse = $this->mockAuthenticationResponse(); $ratingsResponse = $this->createMock(ResponseInterface::class); $ratingsResponse->method('toArray')->willReturn($expectedResponse); $ratingsResponse->method('getStatusCode')->willReturn(200); $this->httpClient->expects($this->exactly(2)) ->method('request') ->willReturnCallback(function ($method, $url) use ($authResponse, $ratingsResponse) { if (str_contains($url, 'auth.mangadex.org')) { return $authResponse; } return $ratingsResponse; }); $result = $this->client->getMangaRatings(['123']); $this->assertEquals($expectedResponse, $result); } }