diff --git a/src/Api/GroupsHooks.php b/src/Api/GroupsHooks.php new file mode 100644 index 00000000..e0481984 --- /dev/null +++ b/src/Api/GroupsHooks.php @@ -0,0 +1,97 @@ + + * (c) Graham Campbell + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gitlab\Api; + +class GroupsHooks extends AbstractApi +{ + /** + * @param array $parameters { + * + * @var int $page page number (default: 1) + * @var int $per_page number of items to list per page (default: 20, max: 100) + * } + */ + public function all($group_id, array $parameters = []): mixed + { + $resolver = $this->createOptionsResolver(); + + $path = 'groups/'.self::encodePath($group_id).'/hooks'; + + return $this->get($path, $resolver->resolve($parameters)); + } + + public function show(int|string $group_id, int $hook_id): mixed + { + return $this->get('groups/'.self::encodePath($group_id).'/hooks/'.self::encodePath($hook_id)); + } + + public function create(int|string $group_id, array $params): mixed + { + return $this->post('groups/'.self::encodePath($group_id).'/hooks', $params); + } + + public function update(int|string $group_id, int $hook_id, array $params): mixed + { + return $this->put('groups/'.self::encodePath($group_id).'/hooks/'.self::encodePath($hook_id), $params); + } + + public function remove(int|string $group_id, int $hook_id): mixed + { + return $this->delete('groups/'.self::encodePath($group_id).'/hooks/'.self::encodePath($hook_id)); + } + + public function allEvents(int|string $group_id, int $hook_id): mixed + { + return $this->get('groups/'.self::encodePath($group_id).'/hooks/'.self::encodePath($hook_id).'/events'); + } + + public function resend(int|string $group_id, int $hook_id, int $hook_event_id): mixed + { + return $this->post('groups/'.self::encodePath($group_id).'/hooks/'.self::encodePath($hook_id).'/events/'.self::encodePath($hook_event_id).'/resend'); + } + + public function test(int|string $group_id, int $hook_id, string $trigger): mixed + { + return $this->post('groups/'.self::encodePath($group_id).'/hooks/'.self::encodePath($hook_id).'/test/'.self::encodePath($trigger)); + } + + public function setCustomHeader(int|string $group_id, int $hook_id, string $key, string $value): mixed + { + $params = [ + 'value' => $value, + ]; + + return $this->put('groups/'.self::encodePath($group_id).'/hooks/'.self::encodePath($hook_id).'/custom_headers/'.self::encodePath($key), $params); + } + + public function deleteCustomHeader(int|string $group_id, int $hook_id, string $key): mixed + { + return $this->delete('groups/'.self::encodePath($group_id).'/hooks/'.self::encodePath($hook_id).'/custom_headers/'.self::encodePath($key)); + } + + public function setUrlVariable(int|string $group_id, int $hook_id, string $key, string $value): mixed + { + $params = [ + 'value' => $value, + ]; + + return $this->put('groups/'.self::encodePath($group_id).'/hooks/'.self::encodePath($hook_id).'/url_variables/'.self::encodePath($key), $params); + } + + public function deleteUrlVariable(int|string $group_id, int $hook_id, string $key): mixed + { + return $this->delete('groups/'.self::encodePath($group_id).'/hooks/'.self::encodePath($hook_id).'/url_variables/'.self::encodePath($key)); + } +} diff --git a/src/Client.php b/src/Client.php index ee4ff8a7..7d1aa87e 100644 --- a/src/Client.php +++ b/src/Client.php @@ -21,6 +21,7 @@ use Gitlab\Api\Groups; use Gitlab\Api\GroupsBoards; use Gitlab\Api\GroupsEpics; +use Gitlab\Api\GroupsHooks; use Gitlab\Api\GroupsMilestones; use Gitlab\Api\IssueBoards; use Gitlab\Api\IssueLinks; @@ -165,6 +166,11 @@ public function groupsEpics(): GroupsEpics return new GroupsEpics($this); } + public function groupsHooks(): GroupsHooks + { + return new GroupsHooks($this); + } + public function groupsMilestones(): GroupsMilestones { return new GroupsMilestones($this); diff --git a/tests/Api/GroupHooksTest.php b/tests/Api/GroupHooksTest.php new file mode 100644 index 00000000..abc31298 --- /dev/null +++ b/tests/Api/GroupHooksTest.php @@ -0,0 +1,220 @@ + + * (c) Graham Campbell + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gitlab\Tests\Api; + +use Gitlab\Api\GroupsHooks; +use PHPUnit\Framework\Attributes\Test; + +class GroupHooksTest extends TestCase +{ + #[Test] + public function shouldGetAllHooks(): void + { + $expectedArray = [ + ['id' => 1, 'url' => 'https://example.com/webhook-trigger/1'], + ['id' => 2, 'url' => 'https://example.com/webhook-trigger/2'], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/1/hooks', []) + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->all(1)); + } + + #[Test] + public function shouldShowHook(): void + { + $expectedArray = ['id' => 2, 'url' => 'https://example.com/webhook-trigger/2']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/1/hooks/2') + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->show(1, 2)); + } + + #[Test] + public function shouldCreateHook(): void + { + $expectedArray = ['id' => 3, 'url' => 'https://example.com/webhook-trigger/3']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('groups/1/hooks', ['url' => $expectedArray['url']]) + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->create(1, ['url' => $expectedArray['url']])); + } + + #[Test] + public function shouldUpdateHook(): void + { + $expectedArray = ['id' => 2, 'url' => 'https://example.com/webhook-trigger-rename/2']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('put') + ->with('groups/1/hooks/2', ['url' => $expectedArray['url'], 'name' => 'Test Webhook']) + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->update(1, 2, ['url' => $expectedArray['url'], 'name' => 'Test Webhook'])); + } + + #[Test] + public function shouldRemoveHook(): void + { + $expectedBool = true; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('groups/1/hooks/2') + ->willReturn($expectedBool); + + $this->assertEquals($expectedBool, $api->remove(1, 2)); + } + + #[Test] + public function shouldGetAllEvents(): void + { + $expectedArray = [ + [ + 'id' => 1, + 'url' => 'https://example.com/webhook-trigger/2', + 'trigger' => 'push_hooks', + ], [ + 'id' => 2, + 'url' => 'https://example.com/webhook-trigger/2', + 'trigger' => 'push_hooks', + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/1/hooks/2/events') + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->allEvents(1, 2)); + } + + #[Test] + public function shouldResend(): void + { + $expectedArray = [ + 'response_status' => 200, + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('groups/1/hooks/2/events/3/resend') + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->resend(1, 2, 3)); + } + + #[Test] + public function shouldTest(): void + { + $expectedArray = [ + 'message' => '201 Created', + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('groups/1/hooks/2/test/issues_events') + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->test(1, 2, 'issues_events')); + } + + #[Test] + public function shouldSetCustomHeader(): void + { + $expected = ''; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('put') + ->with('groups/1/hooks/2/custom_headers/X-Header', ['value' => 'Test']) + ->willReturn($expected) + ; + + $this->assertEquals($expected, $api->setCustomHeader(1, 2, 'X-Header', 'Test')); + } + + #[Test] + public function shouldDeleteCustomHeader(): void + { + $expectedBool = true; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('groups/1/hooks/2/custom_headers/X-Header') + ->willReturn($expectedBool); + + $this->assertEquals($expectedBool, $api->deleteCustomHeader(1, 2, 'X-Header')); + } + + #[Test] + public function shouldSetUrlVariable(): void + { + $expected = ''; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('put') + ->with('groups/1/hooks/2/url_variables/testvar', ['value' => '123']) + ->willReturn($expected) + ; + + $this->assertEquals($expected, $api->setUrlVariable(1, 2, 'testvar', '123')); + } + + #[Test] + public function shouldDeleteUrlVariable(): void + { + $expectedBool = true; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('groups/1/hooks/2/url_variables/testvar') + ->willReturn($expectedBool); + + $this->assertEquals($expectedBool, $api->deleteUrlVariable(1, 2, 'testvar')); + } + + protected function getApiClass(): string + { + return GroupsHooks::class; + } +}