diff --git a/Makefile b/Makefile index 998f6d5..50ea41d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,10 @@ PHP_CS_RULES=@Symfony,-global_namespace_import .PHONY: test -test: check-style check-rules +test: check-style check-rules phpunit + +.PHONY: phpunit +phpunit: @echo "-- Running phpunit... See output/coverage/index.html " XDEBUG_MODE=coverage vendor/bin/phpunit -c phpunit.xml.dist \ --log-junit output/junit-report.xml \ diff --git a/composer.json b/composer.json index 70f7738..91ca319 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,8 @@ }, "require": { "php": ">=8.3", - "guzzlehttp/guzzle": "~7.0" + "guzzlehttp/guzzle": "~7.0", + "psr/log": "^3.0" }, "require-dev": { "phpunit/phpunit": "^12", diff --git a/src/AbstractClient.php b/src/AbstractClient.php index c07a263..7e17d14 100644 --- a/src/AbstractClient.php +++ b/src/AbstractClient.php @@ -12,10 +12,8 @@ */ abstract class AbstractClient implements ClientInterface { - /** - * @var GuzzleHttpClient - */ - protected $httpClient; + private const DEFAULT_PER_PAGE = 50; + private const MAX_PAGES = 1000; /** * @var LoggerInterface @@ -24,9 +22,12 @@ abstract class AbstractClient implements ClientInterface /** * Constructor with an httpClient ready to performs API requests. + * + * @param string $limitPerPageParam 'per_page' (GitLab, GitHub) or 'limit' (Gogs, Gitea) */ protected function __construct( - GuzzleHttpClient $httpClient, + protected GuzzleHttpClient $httpClient, + private string $limitPerPageParam, ?LoggerInterface $logger = null, ) { $this->httpClient = $httpClient; @@ -50,6 +51,11 @@ protected function getLogger(): LoggerInterface */ abstract protected function createProject(array $rawProject): ProjectInterface; + public function find(FindOptions $options): array + { + return iterator_to_array($this->getProjects($options), false); + } + /** * Get projets for a given path with parameters. * @@ -57,7 +63,7 @@ abstract protected function createProject(array $rawProject): ProjectInterface; * * @return ProjectInterface[] */ - protected function getProjects( + private function fetchProjects( string $path, array $params = [], ): array { @@ -73,6 +79,37 @@ protected function getProjects( return $projects; } + /** + * Fetch all pages for a given path with query params. + * + * @param string $path ex : "/api/v4/projects" + * @param ProjectFilterInterface $projectFilter client side filtering + * @param array $extraParams ex : ['affiliation' => 'owner'] + * + * @return iterable + */ + protected function fetchAllPages( + string $path, + ProjectFilterInterface $projectFilter, + array $extraParams = [], + ): iterable { + for ($page = 1; $page <= self::MAX_PAGES; ++$page) { + $params = array_merge($extraParams, [ + 'page' => $page, + $this->limitPerPageParam => self::DEFAULT_PER_PAGE, + ]); + $projects = $this->fetchProjects($path, $params); + if (empty($projects)) { + break; + } + foreach ($projects as $project) { + if ($projectFilter->isAccepted($project)) { + yield $project; + } + } + } + } + /** * Implode params to performs HTTP request. * @@ -87,24 +124,4 @@ protected function implodeParams(array $params): string return implode('&', $parts); } - - /** - * Helper to apply filter to a project list. - * - * @param ProjectInterface[] $projects - * - * @return ProjectInterface[] - */ - protected function filter(array $projects, ProjectFilterInterface $filter): array - { - $result = []; - foreach ($projects as $project) { - if (!$filter->isAccepted($project)) { - continue; - } - $result[] = $project; - } - - return $result; - } } diff --git a/src/ClientFactory.php b/src/ClientFactory.php index c8788f4..e9cd6bd 100644 --- a/src/ClientFactory.php +++ b/src/ClientFactory.php @@ -4,13 +4,13 @@ use GuzzleHttp\Client as GuzzleHttpClient; use MBO\RemoteGit\Exception\ClientNotFoundException; +use MBO\RemoteGit\Exception\ProtocolNotSupportedException; use MBO\RemoteGit\Github\GithubClient; use MBO\RemoteGit\Gitlab\GitlabClient; use MBO\RemoteGit\Gogs\GogsClient; use MBO\RemoteGit\Helper\ClientHelper; use MBO\RemoteGit\Helper\LoggerHelper; use MBO\RemoteGit\Http\TokenType; -use MBO\RemoteGit\Local\LocalClient; use Psr\Log\LoggerInterface; /** @@ -39,7 +39,6 @@ private function __construct() $this->register(GitlabClient::class); $this->register(GithubClient::class); $this->register(GogsClient::class); - $this->register(LocalClient::class); } /** @@ -97,9 +96,9 @@ public function createGitClient( throw new ClientNotFoundException($options->getType(), $this->getTypes()); } - /* Handle LocalClient */ - if (LocalClient::TYPE === $options->getType()) { - return new LocalClient($options->getUrl(), $logger); + /* handle removed LocalClient */ + if ('local' === $options->getType()) { + throw new ClientNotFoundException($options->getType(), $this->getTypes()); } /* Force github API URL */ @@ -141,8 +140,11 @@ public function createGitClient( public static function detectClientClass(string $url): string { $scheme = parse_url($url, PHP_URL_SCHEME); + if (!is_string($scheme)) { + $scheme = 'file'; + } if (!in_array($scheme, ['http', 'https'])) { - return LocalClient::class; + throw new ProtocolNotSupportedException($scheme, $url); } $hostname = parse_url($url, PHP_URL_HOST); diff --git a/src/ClientInterface.php b/src/ClientInterface.php index cb5b52f..1129381 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -10,9 +10,18 @@ */ interface ClientInterface { + /** + * Find projects according to options. + * + * @return iterable + */ + public function getProjects(FindOptions $options): iterable; + /** * Find projects using API calls. * + * @deprecated use getProjects instead + * * @return ProjectInterface[] */ public function find(FindOptions $options): array; diff --git a/src/Exception/ProtocolNotSupportedException.php b/src/Exception/ProtocolNotSupportedException.php new file mode 100644 index 0000000..776d67f --- /dev/null +++ b/src/Exception/ProtocolNotSupportedException.php @@ -0,0 +1,17 @@ +getUsers()) && empty($options->getOrganizations())) { - throw new RequiredParameterException('[GithubClient]Define at least an org or a user to use find'); + throw new RequiredParameterException('[GithubClient]Define at least an org or an user'); } foreach ($options->getUsers() as $user) { - $result = array_merge($result, $this->findByUser( + yield from $this->findByUser( $user, $options->getFilter() - )); + ); } foreach ($options->getOrganizations() as $org) { - $result = array_merge($result, $this->findByOrg( + yield from $this->findByOrg( $org, $options->getFilter() - )); + ); } - - return $result; } /** @@ -81,70 +76,41 @@ public function find(FindOptions $options): array protected function findByUser( string $user, ProjectFilterInterface $projectFilter, - ) { + ): iterable { /* * Use /user/repos?affiliation=owner for special user _me_ */ if ('_me_' == $user) { - return $this->fetchAllPages( + yield from $this->fetchAllPages( '/user/repos', $projectFilter, - [ + extraParams: [ 'affiliation' => 'owner', ] ); + } else { + yield from $this->fetchAllPages( + '/users/'.$user.'/repos', + $projectFilter + ); } - - return $this->fetchAllPages( - '/users/'.$user.'/repos', - $projectFilter - ); } /** - * Find projects by username. + * Find projects by org name. * - * @return ProjectInterface[] + * @return iterable */ protected function findByOrg( string $org, ProjectFilterInterface $projectFilter, - ) { - return $this->fetchAllPages( + ): iterable { + yield from $this->fetchAllPages( '/orgs/'.$org.'/repos', $projectFilter ); } - /** - * Fetch all pages for a given URI. - * - * @param string $path such as '/orgs/IGNF/repos' or '/users/mborne/repos' - * @param array $extraParams - * - * @return ProjectInterface[] - */ - private function fetchAllPages( - string $path, - ProjectFilterInterface $projectFilter, - array $extraParams = [], - ): array { - $result = []; - for ($page = 1; $page <= self::MAX_PAGES; ++$page) { - $params = array_merge($extraParams, [ - 'page' => $page, - 'per_page' => self::DEFAULT_PER_PAGE, - ]); - $projects = $this->getProjects($path, $params); - if (empty($projects)) { - break; - } - $result = array_merge($result, $this->filter($projects, $projectFilter)); - } - - return $result; - } - public function getRawFile( ProjectInterface $project, $filePath, diff --git a/src/Gitlab/GitlabClient.php b/src/Gitlab/GitlabClient.php index e6872b1..12d771a 100644 --- a/src/Gitlab/GitlabClient.php +++ b/src/Gitlab/GitlabClient.php @@ -25,9 +25,7 @@ class GitlabClient extends AbstractClient { public const TYPE = 'gitlab-v4'; public const TOKEN_TYPE = TokenType::PRIVATE_TOKEN; - - public const DEFAULT_PER_PAGE = 50; - public const MAX_PAGES = 10000; + private const LIMIT_PER_PAGE_PARAM = 'per_page'; /** * Constructor with an http client and a logger. @@ -36,7 +34,7 @@ public function __construct( GuzzleHttpClient $httpClient, ?LoggerInterface $logger = null, ) { - parent::__construct($httpClient, $logger); + parent::__construct($httpClient, self::LIMIT_PER_PAGE_PARAM, $logger); } protected function createProject(array $rawProject): GitlabProject @@ -44,42 +42,38 @@ protected function createProject(array $rawProject): GitlabProject return new GitlabProject($rawProject); } - public function find(FindOptions $options): array + public function getProjects(FindOptions $options): iterable { /* find all projects applying optional search */ if (empty($options->getUsers()) && empty($options->getOrganizations())) { - return $this->findBySearch($options); + yield from $this->findBySearch($options); } - $result = []; foreach ($options->getUsers() as $user) { - $result = array_merge($result, $this->findByUser( + yield from $this->findByUser( $user, $options->getFilter() - )); + ); } foreach ($options->getOrganizations() as $org) { - $result = array_merge($result, $this->findByGroup( + yield from $this->findByGroup( $org, $options->getFilter() - )); + ); } - - return $result; } /** * Find projects by username. * - * @return ProjectInterface[] + * @return iterable */ protected function findByUser( string $user, ProjectFilterInterface $projectFilter, - ): array { - return $this->fetchAllPages( + ): iterable { + yield from $this->fetchAllPages( '/api/v4/users/'.urlencode($user).'/projects', - [], $projectFilter ); } @@ -87,15 +81,14 @@ protected function findByUser( /** * Find projects by group. * - * @return ProjectInterface[] + * @return iterable */ protected function findByGroup( string $group, ProjectFilterInterface $projectFilter, - ): array { - return $this->fetchAllPages( + ): iterable { + yield from $this->fetchAllPages( '/api/v4/groups/'.urlencode($group).'/projects', - [], $projectFilter ); } @@ -103,9 +96,9 @@ protected function findByGroup( /** * Find all projects using option search. * - * @return ProjectInterface[] + * @return iterable */ - protected function findBySearch(FindOptions $options) + protected function findBySearch(FindOptions $options): iterable { $path = '/api/v4/projects'; $params = []; @@ -113,42 +106,13 @@ protected function findBySearch(FindOptions $options) $params['search'] = $options->getSearch(); } - return $this->fetchAllPages( + yield from $this->fetchAllPages( $path, - $params, - $options->getFilter() + $options->getFilter(), + $params ); } - /** - * Fetch all pages for a given path with query params. - * - * @param string $path ex : "/api/v4/projects" - * @param array $params ex : array('search'=>'sample-composer') - * - * @return ProjectInterface[] - */ - private function fetchAllPages( - string $path, - array $params, - ProjectFilterInterface $projectFilter, - ) { - $result = []; - - for ($page = 1; $page <= self::MAX_PAGES; ++$page) { - $params['page'] = $page; - $params['per_page'] = self::DEFAULT_PER_PAGE; - - $projects = $this->getProjects($path, $params); - if (empty($projects)) { - break; - } - $result = array_merge($result, $this->filter($projects, $projectFilter)); - } - - return $result; - } - public function getRawFile( ProjectInterface $project, string $filePath, diff --git a/src/Gogs/GogsClient.php b/src/Gogs/GogsClient.php index b03c761..b6bffdd 100644 --- a/src/Gogs/GogsClient.php +++ b/src/Gogs/GogsClient.php @@ -20,14 +20,13 @@ class GogsClient extends AbstractClient { public const TYPE = 'gogs-v1'; public const TOKEN_TYPE = TokenType::AUTHORIZATION_TOKEN; - - public const DEFAULT_PER_PAGE = 1000; + private const LIMIT_PER_PAGE_PARAM = 'limit'; public function __construct( GuzzleHttpClient $httpClient, ?LoggerInterface $logger = null, ) { - parent::__construct($httpClient, $logger); + parent::__construct($httpClient, self::LIMIT_PER_PAGE_PARAM, $logger); } protected function createProject(array $rawProject): GogsProject @@ -35,46 +34,38 @@ protected function createProject(array $rawProject): GogsProject return new GogsProject($rawProject); } - public function find(FindOptions $options): array + public function getProjects(FindOptions $options): iterable { if (empty($options->getUsers()) && empty($options->getOrganizations())) { - return $this->findByCurrentUser( + yield from $this->findByCurrentUser( $options->getFilter() ); } - $result = []; foreach ($options->getUsers() as $user) { - $result = array_merge($result, $this->findByUser( + yield from $this->findByUser( $user, $options->getFilter() - )); + ); } foreach ($options->getOrganizations() as $org) { - $result = array_merge($result, $this->findByOrg( + yield from $this->findByOrg( $org, $options->getFilter() - )); + ); } - - return $result; } /** * Find projects for current user. * - * @return ProjectInterface[] + * @return iterable */ protected function findByCurrentUser( ProjectFilterInterface $projectFilter, - ): array { - return $this->filter( - $this->getProjects( - '/api/v1/user/repos', - [ - 'limit' => self::DEFAULT_PER_PAGE, - ] - ), + ): iterable { + yield from $this->fetchAllPages( + '/api/v1/user/repos', $projectFilter ); } @@ -82,19 +73,14 @@ protected function findByCurrentUser( /** * Find projects by username. * - * @return ProjectInterface[] + * @return iterable */ protected function findByUser( string $user, ProjectFilterInterface $projectFilter, - ): array { - return $this->filter( - $this->getProjects( - '/api/v1/users/'.$user.'/repos', - [ - 'limit' => self::DEFAULT_PER_PAGE, - ] - ), + ): iterable { + yield from $this->fetchAllPages( + '/api/v1/users/'.$user.'/repos', $projectFilter ); } @@ -102,19 +88,14 @@ protected function findByUser( /** * Find projects by organization. * - * @return ProjectInterface[] + * @return iterable */ protected function findByOrg( string $org, ProjectFilterInterface $projectFilter, - ): array { - return $this->filter( - $this->getProjects( - '/api/v1/orgs/'.$org.'/repos', - [ - 'limit' => self::DEFAULT_PER_PAGE, - ] - ), + ): iterable { + yield from $this->fetchAllPages( + '/api/v1/orgs/'.$org.'/repos', $projectFilter ); } diff --git a/src/Local/LocalClient.php b/src/Local/LocalClient.php deleted file mode 100644 index ecd87b5..0000000 --- a/src/Local/LocalClient.php +++ /dev/null @@ -1,158 +0,0 @@ -rootPath = $rootPath; - $this->logger = LoggerHelper::handleNull($logger); - } - - public function find(FindOptions $options): array - { - $projects = []; - - $projectFolders = []; - $this->findProjectFolders($this->rootPath, $projectFolders); - foreach ($projectFolders as $projectFolder) { - $project = $this->createLocalProject($projectFolder); - if (!$options->getFilter()->isAccepted($project)) { - continue; - } - $projects[] = $project; - } - - return $projects; - } - - /** - * Create a LocalProject retreiving metadata from absolute path to project. - * - * @param string $projectFolder - * - * @return LocalProject - */ - public function createLocalProject($projectFolder) - { - /* relativize path and remove .git for bare repositories */ - $fullName = substr($projectFolder, strlen($this->rootPath) + 1); - $isBare = false; - if ('.git' === substr($projectFolder, -4)) { - $isBare = true; - $fullName = substr($fullName, 0, strlen($fullName) - 4); - } - // TODO remove trailing .git for bare repositories - $rawMetadata = [ - 'id' => sha1($projectFolder), - 'is_bare' => $isBare, - 'full_path' => $projectFolder, - 'full_name' => $fullName, - 'head_branch' => 'master', // TODO - ]; - - return new LocalProject($rawMetadata); - } - - /** - * Retreive absolute path to project folders. - * - * TODO use something like "git rev-parse --git-dir" to validate - * folders - * - * @param string $parentPath absolute path to a given folder - * @param string[] $projectFolders - */ - protected function findProjectFolders(string $parentPath, array &$projectFolders): void - { - $this->logger->debug("Checking if $parentPath is a git repository ..."); - $items = scandir($parentPath); - assert(false !== $items); - foreach ($items as $item) { - if ('.' === $item || '..' === $item) { - continue; - } - $itemPath = $parentPath.DIRECTORY_SEPARATOR.$item; - if (!is_dir($itemPath)) { - continue; - } - if ('.git' === $item) { - /* non bare repository containing a .git directory */ - $this->logger->info(sprintf('Git repository found : %s', $parentPath)); - $projectFolders[] = $parentPath; - } elseif ('.git' === substr($itemPath, -4)) { - /* bare repository with folder name ending with .git */ - $this->logger->info(sprintf('Git bare repository found : %s', $itemPath)); - $projectFolders[] = $itemPath; - } else { - /* recursive search */ - $this->findProjectFolders($itemPath, $projectFolders); - } - } - } - - public function getRawFile( - ProjectInterface $project, - string $filePath, - string $ref, - ): string { - $cmd = sprintf( - 'git show %s:%s', - escapeshellarg($ref), - escapeshellarg($filePath) - ); - $cwd = $project->getHttpUrl(); - - $pipes = []; - $proc = proc_open($cmd, [ - 1 => ['pipe', 'w'], - 2 => ['pipe', 'w'], - ], $pipes, $cwd); - - $stdout = stream_get_contents($pipes[1]); - fclose($pipes[1]); - $stderr = stream_get_contents($pipes[2]); - fclose($pipes[2]); - if (false === $proc || 0 !== proc_close($proc)) { - $this->logger->error(sprintf('command fails : %s', $stderr), [ - 'cmd' => $cmd, - 'cwd' => $cwd, - ]); - throw new RawFileNotFoundException($filePath, $ref); - } - - assert(false !== $stdout); - - return $stdout; - } -} diff --git a/src/Local/LocalProject.php b/src/Local/LocalProject.php deleted file mode 100644 index 972bb54..0000000 --- a/src/Local/LocalProject.php +++ /dev/null @@ -1,59 +0,0 @@ - $rawMetadata - */ - public function __construct(private array $rawMetadata) - { - } - - public function getId(): string - { - return $this->rawMetadata['id']; - } - - public function getName(): string - { - return $this->rawMetadata['full_name']; - } - - public function getDescription(): string - { - return ''; - } - - public function getDefaultBranch(): ?string - { - return $this->rawMetadata['head_branch']; - } - - public function getHttpUrl(): string - { - return $this->rawMetadata['full_path']; - } - - public function isArchived(): bool - { - return false; // Always returns false for LocalClient - } - - public function getVisibility(): ?ProjectVisibility - { - return null; // Always returns null for LocalClient - } - - public function getRawMetadata(): array - { - return $this->rawMetadata; - } -} diff --git a/src/ProjectInterface.php b/src/ProjectInterface.php index 441bb96..a942fe9 100644 --- a/src/ProjectInterface.php +++ b/src/ProjectInterface.php @@ -21,8 +21,6 @@ public function getName(): string; /** * Get project description from API. - * - * @warning This method will always return empty string for LocalClient. */ public function getDescription(): string; @@ -38,15 +36,11 @@ public function getHttpUrl(): string; /** * True if the project is archived. - * - * @warning This method will always return false for LocalClient. */ public function isArchived(): bool; /** * Get project visibility. - * - * @warning This method will always return null for LocalClient. */ public function getVisibility(): ?ProjectVisibility; diff --git a/tests/ClientFactoryTest.php b/tests/ClientFactoryTest.php index 5475f58..178a214 100644 --- a/tests/ClientFactoryTest.php +++ b/tests/ClientFactoryTest.php @@ -5,10 +5,10 @@ use MBO\RemoteGit\ClientFactory; use MBO\RemoteGit\ClientOptions; use MBO\RemoteGit\Exception\ClientNotFoundException; +use MBO\RemoteGit\Exception\ProtocolNotSupportedException; use MBO\RemoteGit\Github\GithubClient; use MBO\RemoteGit\Gitlab\GitlabClient; use MBO\RemoteGit\Gogs\GogsClient; -use MBO\RemoteGit\Local\LocalClient; class ClientFactoryTest extends TestCase { @@ -17,7 +17,7 @@ public function testGetTypes(): void $clientFactory = ClientFactory::getInstance(); $types = $clientFactory->getTypes(); - $this->assertCount(4, $types); + $this->assertCount(3, $types); } public function testHasType(): void @@ -72,15 +72,42 @@ public function testDetectClientType(): void ClientFactory::detectClientClass('https://gitea.example.com') ); - $this->assertEquals( - LocalClient::class, - ClientFactory::detectClientClass('/path/to/a/folder') - ); - // fallback to gitlab for satis-gitlab original implementation $this->assertEquals( GitlabClient::class, ClientFactory::detectClientClass('https://something-else.com') ); } + + public function testRemovedLocalClient(): void + { + $thrownException = null; + try { + ClientFactory::detectClientClass('/path/to/a/folder'); + } catch (\Exception $e) { + $thrownException = $e; + } + $this->assertNotNull($thrownException); + $this->assertInstanceOf(ProtocolNotSupportedException::class, $thrownException); + $this->assertEquals( + "protocol 'file' for '/path/to/a/folder' is not supported (LocalClient has been removed)", + $thrownException->getMessage() + ); + } + + public function testGitProtocol(): void + { + $thrownException = null; + try { + ClientFactory::detectClientClass('git://github.com/mborne'); + } catch (\Exception $e) { + $thrownException = $e; + } + $this->assertNotNull($thrownException); + $this->assertInstanceOf(ProtocolNotSupportedException::class, $thrownException); + $this->assertEquals( + "protocol 'git' for 'git://github.com/mborne' is not supported (use HTTPS)", + $thrownException->getMessage() + ); + } } diff --git a/tests/GitlabClientTest.php b/tests/GitlabClientTest.php index f959b88..6230f3d 100644 --- a/tests/GitlabClientTest.php +++ b/tests/GitlabClientTest.php @@ -128,6 +128,7 @@ public function testGitlabDotComSearch(): void foreach ($projects as $project) { $projectsByName[$project->getName()] = $project; } + /* check project found */ $this->assertArrayHasKey( 'mborne/sample-composer', diff --git a/tests/LocalClientTest.php b/tests/LocalClientTest.php deleted file mode 100644 index 6b1bb62..0000000 --- a/tests/LocalClientTest.php +++ /dev/null @@ -1,157 +0,0 @@ -exists(self::TEMP_DIR)) { - return; - } - $fs->mkdir(self::TEMP_DIR); - $fs->mkdir(self::TEMP_DIR.'/mborne'); - // non bare repository - exec('cd '.self::TEMP_DIR.'/mborne && git clone https://github.com/mborne/remote-git.git'); - // bare repository - exec('cd '.self::TEMP_DIR.'/mborne && git clone --bare https://github.com/mborne/satis-gitlab.git'); - } - - /** - * Create a LocalClient for sample test directory. - */ - protected function createLocalClient(): LocalClient - { - // folder containing mborne/remote-git and mborne/satis-gitlab - $clientOptions = new ClientOptions(); - $clientOptions - ->setUrl(self::TEMP_DIR) - ; - - /* create client */ - $client = ClientFactory::createClient( - $clientOptions, - new NullLogger() - ); - $this->assertInstanceOf(LocalClient::class, $client); - - return $client; - } - - /** - * Find all projects in test folder. - * - * @return LocalProject[] - */ - protected function findAllProjects(): array - { - /* create client */ - $client = $this->createLocalClient(); - - /* search projects */ - $options = new FindOptions(); - $projects = $client->find($options); - $projectsByName = []; - foreach ($projects as $project) { - $this->assertInstanceOf(LocalProject::class, $project); - $this->assertGettersWorks($project); - $projectsByName[$project->getName()] = $project; - } - - return $projectsByName; - } - - /** - * Ensure that mborne/remote-git and mborne/satis-gitlab are found. - */ - public function testFindAll(): void - { - $projectsByName = $this->findAllProjects(); - $this->assertArrayHasKey( - 'mborne/remote-git', - $projectsByName, - 'Found : '.json_encode(array_keys($projectsByName), JSON_UNESCAPED_SLASHES) - ); - } - - /** - * Ensure that getDescription returns null. - */ - public function getDescription(): void - { - $projects = $this->findAllProjects(); - foreach ($projects as $project) { - $this->assertEmpty($project->getDescription()); - } - } - - /** - * Ensure that isArchived returns false. - */ - public function testIsArchived(): void - { - $projects = $this->findAllProjects(); - foreach ($projects as $project) { - $this->assertFalse($project->isArchived()); - } - } - - /** - * Ensure that isArchived returns public. - */ - public function testGetVisibility(): void - { - $projects = $this->findAllProjects(); - foreach ($projects as $project) { - $this->assertNull($project->getVisibility()); - } - } - - /** - * Check that raw file content can be retreived from non bare repository. - */ - public function testGetRawFileFromNonBareRepository(): void - { - /* test getRawFile */ - $client = $this->createLocalClient(); - $project = $client->createLocalProject(self::TEMP_DIR.'/mborne/remote-git'); - $defaultBranch = $project->getDefaultBranch(); - $this->assertNotNull($defaultBranch); - $readmeContent = $client->getRawFile($project, 'README.md', $defaultBranch); - $this->assertStringContainsString('# mborne/remote-git', $readmeContent); - - /* test getRawFile not found */ - $this->ensureThatRawFileNotFoundThrowsException($client, $project); - } - - /** - * Check that raw file content can be retreived from bare repository. - */ - public function testGetRawFileFromBareRepository(): void - { - /* test getRawFile */ - $client = $this->createLocalClient(); - $project = $client->createLocalProject(self::TEMP_DIR.'/mborne/satis-gitlab.git'); - $defaultBranch = $project->getDefaultBranch(); - $this->assertNotNull($defaultBranch); - $readmeContent = $client->getRawFile($project, 'composer.json', $defaultBranch); - $this->assertStringContainsString('symfony/console', $readmeContent); - - /* test getRawFile not found */ - $this->ensureThatRawFileNotFoundThrowsException($client, $project); - } -}