From 7cfc7d0fa762de429fc08442ce72443112b07b7c Mon Sep 17 00:00:00 2001 From: Maxcastel Date: Wed, 30 Sep 2026 11:33:31 +0200 Subject: [PATCH] Add Projects::downloadUpload() for the markdown uploads download endpoint --- src/Api/Projects.php | 9 +++++++++ tests/Api/ProjectsTest.php | 15 +++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Api/Projects.php b/src/Api/Projects.php index 080d7278..86756e6e 100644 --- a/src/Api/Projects.php +++ b/src/Api/Projects.php @@ -14,6 +14,7 @@ namespace Gitlab\Api; +use Psr\Http\Message\StreamInterface; use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException; use Symfony\Component\OptionsResolver\Options; @@ -1118,6 +1119,14 @@ public function uploadFile(int|string $project_id, string $file): mixed return $this->post($this->getProjectPath($project_id, 'uploads'), [], [], ['file' => $file]); } + /** + * @see https://docs.gitlab.com/api/project_markdown_uploads/#download-an-uploaded-file-by-secret-and-filename + */ + public function downloadUpload(int|string $project_id, string $secret, string $filename): StreamInterface + { + return $this->getAsResponse($this->getProjectPath($project_id, 'uploads/'.self::encodePath($secret).'/'.self::encodePath($filename)))->getBody(); + } + public function uploadAvatar(int|string $project_id, string $file): mixed { return $this->put('projects/'.self::encodePath($project_id), [], [], ['avatar' => $file]); diff --git a/tests/Api/ProjectsTest.php b/tests/Api/ProjectsTest.php index 3f77081c..ad1af601 100644 --- a/tests/Api/ProjectsTest.php +++ b/tests/Api/ProjectsTest.php @@ -16,6 +16,7 @@ use DateTime; use Gitlab\Api\Projects; +use GuzzleHttp\Psr7\Response; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; @@ -3380,6 +3381,20 @@ public function shouldUploadAvatar(): void \unlink($fileName); } + #[Test] + public function shouldDownloadUpload(): void + { + $returnedStream = new Response(200, [], 'foobar'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('getAsResponse') + ->with('projects/1/uploads/66dbcd21ec5d24ed6ea225176098d52b/example.txt') + ->willReturn($returnedStream); + + $this->assertEquals('foobar', $api->downloadUpload(1, '66dbcd21ec5d24ed6ea225176098d52b', 'example.txt')->getContents()); + } + #[Test] public function shouldAddProtectedTag(): void {