createStub(HttpClientInterface::class), $username, $token, $this->createStub(LoggerInterface::class), $baseUrl, ); } /** @param array> $data raw JSON body, e.g. events or the user lookup */ private function stubResponse(array $data): ResponseInterface { $response = $this->createStub(ResponseInterface::class); $response->method('toArray')->willReturn($data); return $response; } #[Test] public function it_returns_gitlab_as_name(): void { $this->assertSame('gitlab', $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_throws_not_found_exception_when_user_does_not_exist(): void { $client = $this->createStub(HttpClientInterface::class); $client->method('request')->willReturn($this->stubResponse([])); $this->expectException(NotFoundHttpException::class); $provider = $this->makeProvider(client: $client); $provider->resolveFetch($provider->startFetch()); } #[Test] public function it_fetches_events_and_counts_them_by_date(): void { $client = $this->createMock(HttpClientInterface::class); $client->method('request')->willReturnCallback( function (string $method, string $url): ResponseInterface { if (str_contains($url, '/events')) { return $this->stubResponse([ ['created_at' => '2024-06-10T12:00:00.000Z'], ['created_at' => '2024-06-10T14:00:00.000Z'], ['created_at' => '2024-06-11T08:00:00.000Z'], ]); } return $this->stubResponse([['id' => 42]]); } ); $provider = $this->makeProvider(client: $client); $result = $provider->resolveFetch($provider->startFetch()); $this->assertSame(2, $result['2024-06-10']); $this->assertSame(1, $result['2024-06-11']); } #[Test] public function it_fetches_multiple_pages_until_page_has_fewer_than_100_events(): void { $callCount = 0; $client = $this->createMock(HttpClientInterface::class); $client->method('request')->willReturnCallback( function (string $method, string $url) use (&$callCount): ResponseInterface { if (!str_contains($url, '/events')) { return $this->stubResponse([['id' => 42]]); } $callCount++; $data = $callCount === 1 ? array_fill(0, 100, ['created_at' => '2024-06-10T12:00:00.000Z']) : [['created_at' => '2024-06-11T08:00:00.000Z']]; return $this->stubResponse($data); } ); $provider = $this->makeProvider(client: $client); $result = $provider->resolveFetch($provider->startFetch()); $this->assertSame(2, $callCount); $this->assertSame(100, $result['2024-06-10']); $this->assertSame(1, $result['2024-06-11']); } #[Test] public function it_sends_after_and_before_query_params_when_since_and_until_are_given(): void { $capturedQuery = null; $client = $this->createMock(HttpClientInterface::class); $client->method('request')->willReturnCallback( function (string $method, string $url, array $options = []) use (&$capturedQuery): ResponseInterface { if (str_contains($url, '/events')) { $capturedQuery = $options['query']; } return $this->stubResponse(str_contains($url, '/events') ? [] : [['id' => 42]]); } ); $provider = $this->makeProvider(client: $client); $provider->startFetch(new \DateTimeImmutable('2024-01-01'), new \DateTimeImmutable('2024-01-31')); $this->assertSame('2024-01-01', $capturedQuery['after']); $this->assertSame('2024-01-31', $capturedQuery['before']); } }