diff --git a/VERSIONS_HOTLINE/95613 b/VERSIONS_HOTLINE/95613 new file mode 100644 index 0000000000000000000000000000000000000000..a20e2ac377a949f1497e09c24c57e38d3ec02056 --- /dev/null +++ b/VERSIONS_HOTLINE/95613 @@ -0,0 +1 @@ + - ticket #95613 : Redmine : accès aux pièces jointes de la forge via Bokeh \ No newline at end of file diff --git a/application/modules/admin/controllers/RedmineController.php b/application/modules/admin/controllers/RedmineController.php index a6dc51e07e5406fc71a4795bb55a0717e2a38597..5f69c41b0800933f077f4c822630ce85b1247f13 100644 --- a/application/modules/admin/controllers/RedmineController.php +++ b/application/modules/admin/controllers/RedmineController.php @@ -175,6 +175,21 @@ class Admin_RedmineController extends ZendAfi_Controller_Action { } + public function downloadFileAction() { + $library = Class_Bib::find($this->_getParam('id_lib', 0)); + $service = new Class_WebService_Redmine($library); + $fileid = $this->_getParam('fileid'); + + if (!$content = $service->downloadFile($fileid)) { + $this->_helper->notify($this->_('Impossible de télécharger cette pièce jointe')); + $this->_redirectToReferer(); + return; + } + + $this->_helper->binaryDownload($content, $this->_getParam('filename')); + } + + public function uploadFileAction() { if (!$this->_request->isPost()) return $this->_jsonError($this->_('La requête doit être de type POST')); diff --git a/library/Class/WebService/Redmine.php b/library/Class/WebService/Redmine.php index 89c41bab2b3117bea6b1facaf465967e778b1087..3ae9be3ffa6f2966dcbbb0ad1da739471aefe67a 100644 --- a/library/Class/WebService/Redmine.php +++ b/library/Class/WebService/Redmine.php @@ -20,7 +20,7 @@ */ class Class_WebService_Redmine extends Class_WebService_Abstract { - use Trait_Translator; + use Trait_Translator; const CUSTOM_PRIORITY_ID = 5; const CUSTOM_MODULE_ID = 37; @@ -381,8 +381,12 @@ class Class_WebService_Redmine extends Class_WebService_Abstract { public function uploadFile($json) { - return $this->_getAttachmentApi() - ->upload($json); + return $this->_getAttachmentApi()->upload($json); + } + + + public function downloadFile($fileid) { + return $this->_getAttachmentApi()->download($fileid); } diff --git a/library/Class/WebService/Redmine/Issue.php b/library/Class/WebService/Redmine/Issue.php index e3bccad28f6e0c8973cab5ad2ee50175a60d4622..bfb49055070fe2fed501b7b57d3cf35c40f63e1f 100644 --- a/library/Class/WebService/Redmine/Issue.php +++ b/library/Class/WebService/Redmine/Issue.php @@ -139,10 +139,12 @@ class Class_WebService_Redmine_Issue extends Class_Entity { return $view->tag('del', $this->_('Pièce jointe : "%s"', $attachment->getold_value())); - $show_url = sprintf('%s/attachments/download/%s/%s', - Class_AdminVar::get('REDMINE_SERVER_URL'), - $attachment->getname(), - $attachment->getnew_value()); + $show_url = Class_Url::absolute(['module' => 'admin', + 'controller' => 'redmine', + 'action' => 'download-file', + 'id_lib' => $this->getLibrary()->getId(), + 'fileid' => $attachment->getname(), + 'filename' => $attachment->getnew_value()],null,true); return $view->tagAnchor($show_url, $this->_('Pièce jointe : "%s"', $attachment->getnew_value()), ['target' => '_blank']); diff --git a/tests/application/modules/admin/controllers/RedmineControllerTest.php b/tests/application/modules/admin/controllers/RedmineControllerTest.php index 3b84848c1d754d888c1d66658c3e6a7fecc1e992..a94fef7ab9b30f8dcc8630b702034325bcc693f8 100644 --- a/tests/application/modules/admin/controllers/RedmineControllerTest.php +++ b/tests/application/modules/admin/controllers/RedmineControllerTest.php @@ -52,6 +52,7 @@ abstract class Admin_RedmineControllerTestCase extends Admin_AbstractControllerT + class Admin_RedmineControllerTestActionWithNoBibTest extends Admin_RedmineControllerTestCase { public function setUp() { parent::setUp(); @@ -67,6 +68,7 @@ class Admin_RedmineControllerTestActionWithNoBibTest extends Admin_RedmineContro + abstract class Admin_RedmineControllerWithAnnecyLibraryTestCase extends Admin_RedmineControllerTestCase { public function setUp() { @@ -560,6 +562,13 @@ class Admin_RedmineControllerEditIssue34247Test extends Admin_RedmineControllerF public function historyShouldBePresent() { $this->assertXPathContentContains('//legend', 'Historique'); } + + + /** @test */ + public function attachmentShouldLinkToDownloadFile() { + $this->assertXPathContentContains('//a[contains(@href,"download-file/id_lib/1/fileid/456789/filename/proof.jpg")]', 'proof.jpg', $this->_response->getBody()); + } + } @@ -863,3 +872,74 @@ class Admin_RedmineControllerPostEditIssue34247WithAttachmentTest extends Admin_ $this->assertRedirect(); } } + + + +class Admin_RedmineControllerTestActionDownloadAttachmentTest + extends Admin_RedmineControllerWithAnnecyLibraryTestCase { + + public function setUp() { + parent::setUp(); + + $redmine_api = $this->mock() + ->whenCalled('download') + ->with(123) + ->answers('toto'); + + $redmine_client = $this->mock() + ->whenCalled('api') + ->answers($redmine_api); + + Class_WebService_Redmine::setClient($redmine_client); + + $this->dispatch('/admin/redmine/download-file/id_lib/1/fileid/123/filename/test.txt', true); + } + + + /** @test */ + public function responseBodyShouldBeToto() { + $this->assertEquals('toto', $this->_response->getBody()); + } + + + /** @test */ + public function contentTypeShouldBeApplicationOctetStream() { + $this->assertEquals('application/octet-stream; name="test.txt"', + $this->_response->getHeaders()[0]['value']); + } +} + + + +class Admin_RedmineControllerTestActionDownloadEmptyAttachmentTest + extends Admin_RedmineControllerWithAnnecyLibraryTestCase { + + public function setUp() { + parent::setUp(); + + $redmine_api = $this->mock() + ->whenCalled('download') + ->with(123) + ->answers(''); + + $redmine_client = $this->mock() + ->whenCalled('api') + ->answers($redmine_api); + + Class_WebService_Redmine::setClient($redmine_client); + + $this->dispatch('/admin/redmine/download-file/id_lib/1/fileid/123/filename/test.txt', true); + } + + + /** @test */ + public function shouldNotifyError() { + $this->assertFlashMessengerContentContains('Impossible de télécharger cette pièce jointe'); + } + + + /** @test */ + public function shouldRedirect() { + $this->assertRedirect(); + } +} \ No newline at end of file