Bootswatch, Summernote, and Captcheck mods for Mods for HESK (mods-for-hesk.com). In use at support.netsyms.com.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AttachmentHandlerTest.php 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. <?php
  2. namespace BusinessLogic\Attachments;
  3. use BusinessLogic\Exceptions\ValidationException;
  4. use BusinessLogic\Security\UserContext;
  5. use BusinessLogic\Security\UserPrivilege;
  6. use BusinessLogic\Security\UserToTicketChecker;
  7. use BusinessLogic\Tickets\Reply;
  8. use BusinessLogic\Tickets\Ticket;
  9. use DataAccess\Attachments\AttachmentGateway;
  10. use DataAccess\Files\FileDeleter;
  11. use DataAccess\Files\FileWriter;
  12. use DataAccess\Tickets\TicketGateway;
  13. use PHPUnit\Framework\TestCase;
  14. class AttachmentHandlerTest extends TestCase {
  15. /* @var $attachmentHandler AttachmentHandler */
  16. private $attachmentHandler;
  17. /* @var $createAttachmentModel CreateAttachmentForTicketModel */
  18. private $createAttachmentForTicketModel;
  19. /* @var $ticketGateway \PHPUnit_Framework_MockObject_MockObject */
  20. private $ticketGateway;
  21. /* @var $attachmentGateway \PHPUnit_Framework_MockObject_MockObject */
  22. private $attachmentGateway;
  23. /* @var $userToTicketChecker \PHPUnit_Framework_MockObject_MockObject */
  24. private $userToTicketChecker;
  25. /* @var $fileWriter \PHPUnit_Framework_MockObject_MockObject */
  26. private $fileWriter;
  27. /* @var $fileDeleter \PHPUnit_Framework_MockObject_MockObject */
  28. private $fileDeleter;
  29. /* @var $userContext UserContext */
  30. private $userContext;
  31. /* @var $heskSettings array */
  32. private $heskSettings;
  33. protected function setUp() {
  34. $this->ticketGateway = $this->createMock(TicketGateway::class);
  35. $this->attachmentGateway = $this->createMock(AttachmentGateway::class);
  36. $this->fileWriter = $this->createMock(FileWriter::class);
  37. $this->fileDeleter = $this->createMock(FileDeleter::class);
  38. $this->userToTicketChecker = $this->createMock(UserToTicketChecker::class);
  39. $this->heskSettings = array(
  40. 'attach_dir' => 'attachments',
  41. 'attachments' => array(
  42. 'allowed_types' => array('.txt'),
  43. 'max_size' => 999
  44. )
  45. );
  46. $this->attachmentHandler = new AttachmentHandler($this->ticketGateway,
  47. $this->attachmentGateway,
  48. $this->fileWriter,
  49. $this->userToTicketChecker,
  50. $this->fileDeleter);
  51. $this->createAttachmentForTicketModel = new CreateAttachmentForTicketModel();
  52. $this->createAttachmentForTicketModel->attachmentContents = base64_encode('string');
  53. $this->createAttachmentForTicketModel->displayName = 'DisplayName.txt';
  54. $this->createAttachmentForTicketModel->ticketId = 1;
  55. $this->createAttachmentForTicketModel->type = AttachmentType::MESSAGE;
  56. $this->userContext = new UserContext();
  57. }
  58. function testThatValidateThrowsAnExceptionWhenTheAttachmentBodyIsNull() {
  59. //-- Arrange
  60. $this->userToTicketChecker->method('isTicketAccessibleToUser')->willReturn(true);
  61. $this->createAttachmentForTicketModel->attachmentContents = null;
  62. //-- Assert
  63. $this->expectException(ValidationException::class);
  64. $this->expectExceptionMessageRegExp('/CONTENTS_EMPTY/');
  65. //-- Act
  66. $this->attachmentHandler->createAttachmentForTicket($this->createAttachmentForTicketModel, $this->userContext, $this->heskSettings);
  67. }
  68. function testThatValidateThrowsAnExceptionWhenTheAttachmentBodyIsEmpty() {
  69. //-- Arrange
  70. $this->userToTicketChecker->method('isTicketAccessibleToUser')->willReturn(true);
  71. $this->createAttachmentForTicketModel->attachmentContents = '';
  72. //-- Assert
  73. $this->expectException(ValidationException::class);
  74. $this->expectExceptionMessageRegExp('/CONTENTS_EMPTY/');
  75. //-- Act
  76. $this->attachmentHandler->createAttachmentForTicket($this->createAttachmentForTicketModel, $this->userContext, $this->heskSettings);
  77. }
  78. function testThatValidateThrowsAnExceptionWhenTheAttachmentBodyIsInvalidBase64() {
  79. //-- Arrange
  80. $this->markTestSkipped("Skipping due to Gitlab CI issues");
  81. $this->ticketGateway->method('getTicketById')->willReturn(new Ticket());
  82. $this->userToTicketChecker->method('isTicketAccessibleToUser')->willReturn(true);
  83. $this->createAttachmentForTicketModel->attachmentContents = 'invalid base 64';
  84. //-- Assert
  85. $this->expectException(ValidationException::class);
  86. $this->expectExceptionMessageRegExp('/CONTENTS_NOT_BASE_64/');
  87. //-- Act
  88. $this->attachmentHandler->createAttachmentForTicket($this->createAttachmentForTicketModel, $this->userContext, $this->heskSettings);
  89. }
  90. function testThatValidateThrowsAnExceptionWhenTheDisplayNameIsNull() {
  91. //-- Arrange
  92. $this->userToTicketChecker->method('isTicketAccessibleToUser')->willReturn(true);
  93. $this->createAttachmentForTicketModel->displayName = null;
  94. //-- Assert
  95. $this->expectException(ValidationException::class);
  96. $this->expectExceptionMessageRegExp('/DISPLAY_NAME_EMPTY/');
  97. //-- Act
  98. $this->attachmentHandler->createAttachmentForTicket($this->createAttachmentForTicketModel, $this->userContext, $this->heskSettings);
  99. }
  100. function testThatValidateThrowsAnExceptionWhenTheDisplayNameIsEmpty() {
  101. //-- Arrange
  102. $this->userToTicketChecker->method('isTicketAccessibleToUser')->willReturn(true);
  103. $this->createAttachmentForTicketModel->displayName = '';
  104. //-- Assert
  105. $this->expectException(ValidationException::class);
  106. $this->expectExceptionMessageRegExp('/DISPLAY_NAME_EMPTY/');
  107. //-- Act
  108. $this->attachmentHandler->createAttachmentForTicket($this->createAttachmentForTicketModel, $this->userContext, $this->heskSettings);
  109. }
  110. function testThatValidateThrowsAnExceptionWhenTheTicketIdIsNull() {
  111. //-- Arrange
  112. $this->userToTicketChecker->method('isTicketAccessibleToUser')->willReturn(true);
  113. $this->createAttachmentForTicketModel->ticketId = null;
  114. //-- Assert
  115. $this->expectException(ValidationException::class);
  116. $this->expectExceptionMessageRegExp('/TICKET_ID_MISSING/');
  117. //-- Act
  118. $this->attachmentHandler->createAttachmentForTicket($this->createAttachmentForTicketModel, $this->userContext, $this->heskSettings);
  119. }
  120. function testThatValidateThrowsAnExceptionWhenTheTicketIdIsANonPositiveInteger() {
  121. //-- Arrange
  122. $this->userToTicketChecker->method('isTicketAccessibleToUser')->willReturn(true);
  123. $this->createAttachmentForTicketModel->ticketId = 0;
  124. //-- Assert
  125. $this->expectException(ValidationException::class);
  126. $this->expectExceptionMessageRegExp('/TICKET_ID_MISSING/');
  127. //-- Act
  128. $this->attachmentHandler->createAttachmentForTicket($this->createAttachmentForTicketModel, $this->userContext, $this->heskSettings);
  129. }
  130. function testThatValidateThrowsAnExceptionWhenTheFileExtensionIsNotPermitted() {
  131. //-- Arrange
  132. $this->userToTicketChecker->method('isTicketAccessibleToUser')->willReturn(true);
  133. $this->heskSettings['attachments']['allowed_types'] = array('.gif');
  134. $this->createAttachmentForTicketModel->ticketId = 0;
  135. //-- Assert
  136. $this->expectException(ValidationException::class);
  137. $this->expectExceptionMessageRegExp('/EXTENSION_NOT_PERMITTED/');
  138. //-- Act
  139. $this->attachmentHandler->createAttachmentForTicket($this->createAttachmentForTicketModel, $this->userContext, $this->heskSettings);
  140. }
  141. function testThatValidateThrowsAnExceptionWhenTheFileSizeIsLargerThanMaxPermitted() {
  142. //-- Arrange
  143. $this->userToTicketChecker->method('isTicketAccessibleToUser')->willReturn(true);
  144. $this->createAttachmentForTicketModel->attachmentContents = base64_encode("msg");
  145. $this->heskSettings['attachments']['max_size'] = 1;
  146. //-- Assert
  147. $this->expectException(ValidationException::class);
  148. $this->expectExceptionMessageRegExp('/FILE_SIZE_TOO_LARGE/');
  149. //-- Act
  150. $this->attachmentHandler->createAttachmentForTicket($this->createAttachmentForTicketModel, $this->userContext, $this->heskSettings);
  151. }
  152. function testItSavesATicketWithTheProperProperties() {
  153. //-- Arrange
  154. $this->userToTicketChecker->method('isTicketAccessibleToUser')->willReturn(true);
  155. $this->createAttachmentForTicketModel->ticketId = 1;
  156. $ticket = new Ticket();
  157. $ticket->trackingId = 'ABC-DEF-1234';
  158. $this->ticketGateway->method('getTicketById')->with(1, $this->anything())->willReturn($ticket);
  159. $ticketAttachment = new TicketAttachment();
  160. $ticketAttachment->displayName = $this->createAttachmentForTicketModel->displayName;
  161. $ticketAttachment->ticketTrackingId = $ticket->trackingId;
  162. $ticketAttachment->type = 0;
  163. $ticketAttachment->downloadCount = 0;
  164. $ticketAttachment->id = 50;
  165. $this->attachmentGateway->method('createAttachmentForTicket')->willReturn(50);
  166. //-- Act
  167. $actual = $this->attachmentHandler->createAttachmentForTicket($this->createAttachmentForTicketModel, $this->userContext, $this->heskSettings);
  168. //-- Assert
  169. self::assertThat($actual->id, self::equalTo(50));
  170. self::assertThat($actual->downloadCount, self::equalTo(0));
  171. self::assertThat($actual->type, self::equalTo(AttachmentType::MESSAGE));
  172. self::assertThat($actual->ticketTrackingId, self::equalTo($ticket->trackingId));
  173. self::assertThat($actual->displayName, self::equalTo($this->createAttachmentForTicketModel->displayName));
  174. }
  175. function testItSavesTheFileToTheFileSystem() {
  176. //-- Arrange
  177. $this->userToTicketChecker->method('isTicketAccessibleToUser')->willReturn(true);
  178. $this->createAttachmentForTicketModel->ticketId = 1;
  179. $ticket = new Ticket();
  180. $ticket->trackingId = 'ABC-DEF-1234';
  181. $this->ticketGateway->method('getTicketById')->with(1, $this->anything())->willReturn($ticket);
  182. $ticketAttachment = new TicketAttachment();
  183. $ticketAttachment->displayName = $this->createAttachmentForTicketModel->displayName;
  184. $ticketAttachment->ticketTrackingId = $ticket->trackingId;
  185. $ticketAttachment->type = AttachmentType::MESSAGE;
  186. $ticketAttachment->downloadCount = 0;
  187. $ticketAttachment->id = 50;
  188. $this->fileWriter->method('writeToFile')->willReturn(1024);
  189. $this->attachmentGateway->method('createAttachmentForTicket')->willReturn(50);
  190. //-- Act
  191. $actual = $this->attachmentHandler->createAttachmentForTicket($this->createAttachmentForTicketModel, $this->userContext, $this->heskSettings);
  192. //-- Assert
  193. self::assertThat($actual->fileSize, self::equalTo(1024));
  194. }
  195. //-- TODO Test UserToTicketChecker
  196. function testDeleteThrowsAnExceptionWhenTheUserDoesNotHaveAccessToTheTicket() {
  197. //-- Arrange
  198. $ticketId = 1;
  199. $ticket = new Ticket();
  200. $this->ticketGateway->method('getTicketById')
  201. ->with($ticketId, $this->heskSettings)->willReturn($ticket);
  202. $this->userToTicketChecker->method('isTicketAccessibleToUser')
  203. ->with($this->userContext, $ticket, $this->heskSettings, array(UserPrivilege::CAN_EDIT_TICKETS))
  204. ->willReturn(false);
  205. //-- Assert
  206. $this->expectException(\Exception::class);
  207. $this->expectExceptionMessage("User does not have access to ticket {$ticketId} being created / edited!");
  208. //-- Act
  209. $this->attachmentHandler->deleteAttachmentFromTicket($ticketId, 1, $this->userContext, $this->heskSettings);
  210. }
  211. function testDeleteActuallyDeletesTheFile() {
  212. //-- Arrange
  213. $ticketId = 1;
  214. $ticket = new Ticket();
  215. $attachment = new Attachment();
  216. $attachment->id = 5;
  217. $attachment->savedName = 'foobar.txt';
  218. $this->heskSettings['attach_dir'] = 'attach-dir';
  219. $ticket->attachments = array($attachment);
  220. $ticket->replies = array();
  221. $this->ticketGateway->method('getTicketById')->willReturn($ticket);
  222. $this->userToTicketChecker->method('isTicketAccessibleToUser')->willReturn(true);
  223. //-- Assert
  224. $this->fileDeleter->expects($this->once())->method('deleteFile')->with('foobar.txt', 'attach-dir');
  225. //-- Act
  226. $this->attachmentHandler->deleteAttachmentFromTicket($ticketId, 5, $this->userContext, $this->heskSettings);
  227. }
  228. function testDeleteUpdatesTheTicketItselfAndSavesIt() {
  229. //-- Arrange
  230. $ticketId = 1;
  231. $ticket = new Ticket();
  232. $ticket->replies = array();
  233. $attachment = new Attachment();
  234. $attachment->id = 5;
  235. $attachment->savedName = 'foobar.txt';
  236. $this->heskSettings['attach_dir'] = 'attach-dir';
  237. $ticket->attachments = array($attachment);
  238. $this->ticketGateway->method('getTicketById')->willReturn($ticket);
  239. $this->userToTicketChecker->method('isTicketAccessibleToUser')->willReturn(true);
  240. //-- Assert
  241. $this->ticketGateway->expects($this->once())->method('updateAttachmentsForTicket');
  242. //-- Act
  243. $this->attachmentHandler->deleteAttachmentFromTicket($ticketId, 5, $this->userContext, $this->heskSettings);
  244. }
  245. function testDeleteHandlesReplies() {
  246. //-- Arrange
  247. $ticketId = 1;
  248. $ticket = new Ticket();
  249. $reply = new Reply();
  250. $reply->id = 10;
  251. $attachment = new Attachment();
  252. $attachment->id = 5;
  253. $attachment->savedName = 'foobar.txt';
  254. $this->heskSettings['attach_dir'] = 'attach-dir';
  255. $reply->attachments = array($attachment);
  256. $ticket->replies = array(10 => $reply);
  257. $this->ticketGateway->method('getTicketById')->willReturn($ticket);
  258. $this->userToTicketChecker->method('isTicketAccessibleToUser')->willReturn(true);
  259. //-- Assert
  260. $this->ticketGateway->expects($this->once())->method('updateAttachmentsForReply');
  261. //-- Act
  262. $this->attachmentHandler->deleteAttachmentFromTicket($ticketId, 5, $this->userContext, $this->heskSettings);
  263. }
  264. }