createStub(GraphQLQuery::class); $graphqlQuery->method('getGraphQLQuery')->willReturn('query {}'); $graphqlClient = $this->createStub(GraphQLApiClient::class); $graphqlClient->method('buildQuery')->willReturn($graphqlQuery); $registry = $this->createStub(GraphQLApiClientRegistryInterface::class); $registry->method('get')->willReturn($graphqlClient); } return new GitHubProvider( $client ?? $this->createStub(HttpClientInterface::class), $registry, $username, $token, $this->createStub(LoggerInterface::class), ); } private function stubGraphqlResponse(array $weeks): ResponseInterface { $response = $this->createStub(ResponseInterface::class); $response->method('toArray')->willReturn([ 'data' => [ 'user' => [ 'contributionsCollection' => [ 'contributionCalendar' => ['weeks' => $weeks], ], ], ], ]); return $response; } #[Test] public function it_returns_github_as_name(): void { $this->assertSame('github', $this->makeProvider()->getName()); } #[Test] public function it_is_configured_when_credentials_are_set(): void { $this->assertTrue($this->makeProvider()->isConfigured()); } #[Test] public function it_is_not_configured_when_username_is_empty(): void { $this->assertFalse($this->makeProvider(username: '')->isConfigured()); } #[Test] public function it_is_not_configured_when_token_is_empty(): void { $this->assertFalse($this->makeProvider(token: '')->isConfigured()); } #[Test] public function it_parses_contribution_days_from_the_graphql_response(): void { $client = $this->createStub(HttpClientInterface::class); $client->method('request')->willReturn($this->stubGraphqlResponse([ ['contributionDays' => [ ['date' => '2024-06-10', 'contributionCount' => 4], ['date' => '2024-06-11', 'contributionCount' => 2], ]], ])); $result = $this->makeProvider(client: $client)->fetch(); $this->assertSame(4, $result['2024-06-10']); $this->assertSame(2, $result['2024-06-11']); } #[Test] public function it_skips_days_with_zero_contributions(): void { $client = $this->createStub(HttpClientInterface::class); $client->method('request')->willReturn($this->stubGraphqlResponse([ ['contributionDays' => [ ['date' => '2024-06-11', 'contributionCount' => 0], ]], ])); $result = $this->makeProvider(client: $client)->fetch(); $this->assertArrayNotHasKey('2024-06-11', $result); } #[Test] public function it_throws_service_unavailable_exception_on_graphql_errors(): void { $response = $this->createStub(ResponseInterface::class); $response->method('toArray')->willReturn([ 'errors' => [['message' => 'Bad credentials']], ]); $client = $this->createStub(HttpClientInterface::class); $client->method('request')->willReturn($response); $this->expectException(ServiceUnavailableHttpException::class); $this->makeProvider(client: $client)->fetch(); } #[Test] public function it_returns_empty_when_response_has_no_weeks(): void { $client = $this->createStub(HttpClientInterface::class); $client->method('request')->willReturn($this->stubGraphqlResponse([])); $result = $this->makeProvider(client: $client)->fetch(); $this->assertSame([], $result); } }