diff --git a/CHANGELOG.md b/CHANGELOG.md index e2325af3..bcda30e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Add support for project remote mirror read endpoints * Add support for permanent project removal and project restoration * Add support for `regex` and `sort` in `Repositories::branches` +* Add support for `Users::usersContributedProjects` ## [12.0.0] - 2025-02-23 diff --git a/src/Api/Users.php b/src/Api/Users.php index ad5ce9a7..c26264fa 100644 --- a/src/Api/Users.php +++ b/src/Api/Users.php @@ -166,6 +166,36 @@ public function usersProjects(int $id, array $parameters = []): mixed return $this->get('users/'.self::encodePath($id).'/projects', $resolver->resolve($parameters)); } + /** + * @param array $parameters { + * + * @var string $order_by return projects ordered by id, name, path, created_at, updated_at, + * star_count, or last_activity_at fields + * @var string $sort return projects sorted in asc or desc order + * @var bool $simple return only the ID, URL, name, and path of each project + * } + */ + public function usersContributedProjects(int|string $id, array $parameters = []): mixed + { + $resolver = $this->createOptionsResolver(); + $booleanNormalizer = function (Options $resolver, $value): string { + return $value ? 'true' : 'false'; + }; + + $resolver->setDefined('order_by') + ->setAllowedValues('order_by', ['id', 'name', 'path', 'created_at', 'updated_at', 'star_count', 'last_activity_at']) + ; + $resolver->setDefined('sort') + ->setAllowedValues('sort', ['asc', 'desc']) + ; + $resolver->setDefined('simple') + ->setAllowedTypes('simple', 'bool') + ->setNormalizer('simple', $booleanNormalizer) + ; + + return $this->get('users/'.self::encodePath($id).'/contributed_projects', $resolver->resolve($parameters)); + } + /** * @param array $parameters { * diff --git a/tests/Api/UsersTest.php b/tests/Api/UsersTest.php index 383834be..b10a9e3f 100644 --- a/tests/Api/UsersTest.php +++ b/tests/Api/UsersTest.php @@ -287,6 +287,63 @@ public function shouldSearchUsersProjects(): void $this->assertEquals($expectedArray, $api->usersProjects(1, ['search' => 'a project'])); } + #[Test] + public function shouldShowUsersContributedProjects(): void + { + $expectedArray = $this->getUsersProjectsData(); + + $api = $this->getUsersProjectsRequestMock('users/1/contributed_projects', $expectedArray); + + $this->assertEquals($expectedArray, $api->usersContributedProjects(1)); + } + + #[Test] + public function shouldShowUsersContributedProjectsByUsername(): void + { + $expectedArray = $this->getUsersProjectsData(); + + $api = $this->getUsersProjectsRequestMock('users/matt/contributed_projects', $expectedArray); + + $this->assertEquals($expectedArray, $api->usersContributedProjects('matt')); + } + + #[Test] + public function shouldShowUsersContributedProjectsWithLimit(): void + { + $expectedArray = [$this->getUsersProjectsData()[0]]; + + $api = $this->getUsersProjectsRequestMock('users/1/contributed_projects', $expectedArray, ['per_page' => 1]); + + $this->assertEquals($expectedArray, $api->usersContributedProjects(1, ['per_page' => 1])); + } + + #[Test] + public function shouldGetAllUsersContributedProjectsSortedByStars(): void + { + $expectedArray = $this->getUsersProjectsData(); + + $api = $this->getUsersProjectsRequestMock( + 'users/1/contributed_projects', + $expectedArray, + ['page' => 1, 'per_page' => 5, 'order_by' => 'star_count', 'sort' => 'desc'] + ); + + $this->assertEquals( + $expectedArray, + $api->usersContributedProjects(1, ['page' => 1, 'per_page' => 5, 'order_by' => 'star_count', 'sort' => 'desc']) + ); + } + + #[Test] + public function shouldShowSimpleUsersContributedProjects(): void + { + $expectedArray = $this->getUsersProjectsData(); + + $api = $this->getUsersProjectsRequestMock('users/1/contributed_projects', $expectedArray, ['simple' => 'true']); + + $this->assertEquals($expectedArray, $api->usersContributedProjects(1, ['simple' => true])); + } + #[Test] public function shouldShowUsersStarredProjects(): void {