@@ -614,7 +614,84 @@ public function testGetEvent(): void
614614 }
615615 public function testSearchRepositories (): void
616616 {
617- $ this ->markTestSkipped ('Will be implemented in follow-up PR ' );
617+ // Create multiple repositories
618+ $ repo1Name = 'test-search-repo1- ' . \uniqid ();
619+ $ repo2Name = 'test-search-repo2- ' . \uniqid ();
620+ $ repo3Name = 'other-repo- ' . \uniqid ();
621+
622+ $ this ->vcsAdapter ->createRepository (self ::$ owner , $ repo1Name , false );
623+ $ this ->vcsAdapter ->createRepository (self ::$ owner , $ repo2Name , false );
624+ $ this ->vcsAdapter ->createRepository (self ::$ owner , $ repo3Name , false );
625+
626+ try {
627+ // Search without filter - should return all
628+ $ result = $ this ->vcsAdapter ->searchRepositories ('' , self ::$ owner , 1 , 10 );
629+
630+ $ this ->assertIsArray ($ result );
631+ $ this ->assertArrayHasKey ('items ' , $ result );
632+ $ this ->assertArrayHasKey ('total ' , $ result );
633+ $ this ->assertGreaterThanOrEqual (3 , $ result ['total ' ]);
634+
635+ // Search with filter
636+ $ result = $ this ->vcsAdapter ->searchRepositories ('' , self ::$ owner , 1 , 10 , 'test-search ' );
637+
638+ $ this ->assertIsArray ($ result );
639+ $ this ->assertGreaterThanOrEqual (2 , $ result ['total ' ]);
640+
641+ // Verify the filtered repos are in results
642+ $ repoNames = array_column ($ result ['items ' ], 'name ' );
643+ $ this ->assertContains ($ repo1Name , $ repoNames );
644+ $ this ->assertContains ($ repo2Name , $ repoNames );
645+ } finally {
646+ $ this ->vcsAdapter ->deleteRepository (self ::$ owner , $ repo1Name );
647+ $ this ->vcsAdapter ->deleteRepository (self ::$ owner , $ repo2Name );
648+ $ this ->vcsAdapter ->deleteRepository (self ::$ owner , $ repo3Name );
649+ }
650+ }
651+
652+ public function testSearchRepositoriesPagination (): void
653+ {
654+ $ repo1 = 'test-pagination-1- ' . \uniqid ();
655+ $ repo2 = 'test-pagination-2- ' . \uniqid ();
656+
657+ $ this ->vcsAdapter ->createRepository (self ::$ owner , $ repo1 , false );
658+ $ this ->vcsAdapter ->createRepository (self ::$ owner , $ repo2 , false );
659+
660+ try {
661+ $ result = $ this ->vcsAdapter ->searchRepositories ('' , self ::$ owner , 1 , 1 , 'test-pagination ' );
662+
663+ $ this ->assertSame (1 , count ($ result ['items ' ]));
664+ $ this ->assertGreaterThanOrEqual (2 , $ result ['total ' ]);
665+
666+ $ result2 = $ this ->vcsAdapter ->searchRepositories ('' , self ::$ owner , 2 , 1 , 'test-pagination ' );
667+ $ this ->assertSame (1 , count ($ result2 ['items ' ]));
668+
669+ $ result20 = $ this ->vcsAdapter ->searchRepositories ('' , self ::$ owner , 20 , 1 , 'test-pagination ' );
670+ $ this ->assertIsArray ($ result20 );
671+ $ this ->assertEmpty ($ result20 ['items ' ]);
672+
673+ } finally {
674+ $ this ->vcsAdapter ->deleteRepository (self ::$ owner , $ repo1 );
675+ $ this ->vcsAdapter ->deleteRepository (self ::$ owner , $ repo2 );
676+ }
677+ }
678+
679+ public function testSearchRepositoriesNoResults (): void
680+ {
681+ $ result = $ this ->vcsAdapter ->searchRepositories ('' , self ::$ owner , 1 , 10 , 'nonexistent-repo-xyz- ' . \uniqid ());
682+
683+ $ this ->assertIsArray ($ result );
684+ $ this ->assertEmpty ($ result ['items ' ]);
685+ $ this ->assertSame (0 , $ result ['total ' ]);
686+ }
687+
688+ public function testSearchRepositoriesInvalidOwner (): void
689+ {
690+ $ result = $ this ->vcsAdapter ->searchRepositories ('' , 'nonexistent-owner- ' . \uniqid (), 1 , 10 );
691+
692+ $ this ->assertIsArray ($ result );
693+ $ this ->assertEmpty ($ result ['items ' ]);
694+ $ this ->assertSame (0 , $ result ['total ' ]);
618695 }
619696
620697 public function testDeleteRepository (): void
@@ -645,7 +722,18 @@ public function testDeleteNonExistingRepositoryFails(): void
645722
646723 public function testGetOwnerName (): void
647724 {
648- $ this ->markTestSkipped ('Will be implemented in follow-up PR ' );
725+ $ this ->expectException (\Exception::class);
726+ $ this ->expectExceptionMessage ('not applicable for Gitea ' );
727+
728+ $ this ->vcsAdapter ->getOwnerName ('' );
729+ }
730+
731+ public function testGetOwnerNameWithRandomInput (): void
732+ {
733+ $ this ->expectException (\Exception::class);
734+ $ this ->expectExceptionMessage ('not applicable for Gitea ' );
735+
736+ $ this ->vcsAdapter ->getOwnerName ('random-gibberish- ' . \uniqid ());
649737 }
650738
651739 public function testGetPullRequestFromBranch (): void
@@ -760,7 +848,38 @@ public function testCreateFileOnBranch(): void
760848
761849 public function testListBranches (): void
762850 {
763- $ this ->markTestSkipped ('Will be implemented in follow-up PR ' );
851+ $ repositoryName = 'test-list-branches- ' . \uniqid ();
852+ $ this ->vcsAdapter ->createRepository (self ::$ owner , $ repositoryName , false );
853+
854+ try {
855+ // Create initial file on main branch
856+ $ this ->vcsAdapter ->createFile (self ::$ owner , $ repositoryName , 'README.md ' , '# Test ' );
857+
858+ // Create additional branches
859+ $ this ->vcsAdapter ->createBranch (self ::$ owner , $ repositoryName , 'feature-1 ' , 'main ' );
860+ $ this ->vcsAdapter ->createBranch (self ::$ owner , $ repositoryName , 'feature-2 ' , 'main ' );
861+
862+ $ branches = [];
863+ $ maxAttempts = 10 ;
864+ for ($ attempt = 0 ; $ attempt < $ maxAttempts ; $ attempt ++) {
865+ $ branches = $ this ->vcsAdapter ->listBranches (self ::$ owner , $ repositoryName );
866+
867+ if (in_array ('feature-1 ' , $ branches , true ) && in_array ('feature-2 ' , $ branches , true )) {
868+ break ;
869+ }
870+
871+ usleep (500000 );
872+ }
873+
874+ $ this ->assertIsArray ($ branches );
875+ $ this ->assertNotEmpty ($ branches );
876+ $ this ->assertContains ('main ' , $ branches );
877+ $ this ->assertContains ('feature-1 ' , $ branches );
878+ $ this ->assertContains ('feature-2 ' , $ branches );
879+ $ this ->assertGreaterThanOrEqual (3 , count ($ branches ));
880+ } finally {
881+ $ this ->vcsAdapter ->deleteRepository (self ::$ owner , $ repositoryName );
882+ }
764883 }
765884
766885 public function testListRepositoryLanguages (): void
0 commit comments