diff --git a/lib/Service/AssignmentService.php b/lib/Service/AssignmentService.php index 96965f01b..3e69948fe 100644 --- a/lib/Service/AssignmentService.php +++ b/lib/Service/AssignmentService.php @@ -35,6 +35,7 @@ use OCA\Deck\NoPermissionException; use OCA\Deck\NotFoundException; use OCA\Deck\Notification\NotificationHelper; +use OCA\Deck\Validators\AssignmentServiceValidator; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\Entity; use OCP\AppFramework\Db\MultipleObjectsReturnedException; @@ -76,6 +77,11 @@ class AssignmentService { private $eventDispatcher; /** @var string|null */ private $currentUser; + /** + * @var AssignmentServiceValidator + */ + private $assignmentServiceValidator; + public function __construct( PermissionService $permissionService, @@ -86,8 +92,10 @@ public function __construct( ActivityManager $activityManager, ChangeHelper $changeHelper, IEventDispatcher $eventDispatcher, + AssignmentServiceValidator $assignmentServiceValidator, $userId ) { + $this->assignmentServiceValidator = $assignmentServiceValidator; $this->permissionService = $permissionService; $this->cardMapper = $cardMapper; $this->assignedUsersMapper = $assignedUsersMapper; @@ -96,6 +104,8 @@ public function __construct( $this->changeHelper = $changeHelper; $this->activityManager = $activityManager; $this->eventDispatcher = $eventDispatcher; + + $this->assignmentServiceValidator->check(compact('userId')); $this->currentUser = $userId; } @@ -109,13 +119,7 @@ public function __construct( * @throws DoesNotExistException */ public function assignUser($cardId, $userId, int $type = Assignment::TYPE_USER) { - if (is_numeric($cardId) === false) { - throw new BadRequestException('card id must be a number'); - } - - if ($userId === false || $userId === null) { - throw new BadRequestException('user id must be provided'); - } + $this->assignmentServiceValidator->check(compact('cardId', 'userId')); if ($type !== Assignment::TYPE_USER && $type !== Assignment::TYPE_GROUP) { throw new BadRequestException('Invalid type provided for assignemnt'); @@ -168,16 +172,9 @@ public function assignUser($cardId, $userId, int $type = Assignment::TYPE_USER) * @throws MultipleObjectsReturnedException */ public function unassignUser($cardId, $userId, $type = 0) { + $this->assignmentServiceValidator->check(compact('cardId', 'userId')); $this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_EDIT); - if (is_numeric($cardId) === false) { - throw new BadRequestException('card id must be a number'); - } - - if ($userId === false || $userId === null) { - throw new BadRequestException('user must be provided'); - } - $assignments = $this->assignedUsersMapper->findAll($cardId); foreach ($assignments as $assignment) { if ($assignment->getParticipant() === $userId && $assignment->getType() === $type) { diff --git a/lib/Service/AttachmentService.php b/lib/Service/AttachmentService.php index f8b6afc33..371d051d9 100644 --- a/lib/Service/AttachmentService.php +++ b/lib/Service/AttachmentService.php @@ -36,6 +36,7 @@ use OCA\Deck\NotFoundException; use OCA\Deck\Cache\AttachmentCacheHelper; use OCA\Deck\StatusException; +use OCA\Deck\Validators\AttachmentServiceValidator; use OCP\AppFramework\Db\IMapperException; use OCP\AppFramework\Http\Response; use OCP\IL10N; @@ -58,8 +59,10 @@ class AttachmentService { private $activityManager; /** @var ChangeHelper */ private $changeHelper; + /** @var AttachmentServiceValidator */ + private $attachmentServiceValidator; - public function __construct(AttachmentMapper $attachmentMapper, CardMapper $cardMapper, ChangeHelper $changeHelper, PermissionService $permissionService, Application $application, AttachmentCacheHelper $attachmentCacheHelper, $userId, IL10N $l10n, ActivityManager $activityManager) { + public function __construct(AttachmentMapper $attachmentMapper, CardMapper $cardMapper, ChangeHelper $changeHelper, PermissionService $permissionService, Application $application, AttachmentCacheHelper $attachmentCacheHelper, $userId, IL10N $l10n, ActivityManager $activityManager, AttachmentServiceValidator $attachmentServiceValidator) { $this->attachmentMapper = $attachmentMapper; $this->cardMapper = $cardMapper; $this->permissionService = $permissionService; @@ -69,6 +72,7 @@ public function __construct(AttachmentMapper $attachmentMapper, CardMapper $card $this->l10n = $l10n; $this->activityManager = $activityManager; $this->changeHelper = $changeHelper; + $this->attachmentServiceValidator = $attachmentServiceValidator; // Register shipped attachment services // TODO: move this to a plugin based approach once we have different types of attachments @@ -174,17 +178,7 @@ public function count($cardId) { * @throws BadRequestException */ public function create($cardId, $type, $data) { - if (is_numeric($cardId) === false) { - throw new BadRequestException('card id must be a number'); - } - - if ($type === false || $type === null) { - throw new BadRequestException('type must be provided'); - } - - if ($data === false || $data === null) { - //throw new BadRequestException('data must be provided'); - } + $this->attachmentServiceValidator->check(compact('cardId', 'type', 'data')); $this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_EDIT); @@ -269,6 +263,8 @@ public function display($cardId, $attachmentId, $type = 'deck_file') { * @throws NoPermissionException */ public function update($cardId, $attachmentId, $data, $type = 'deck_file') { + $this->attachmentServiceValidator->check(compact('cardId', 'type', 'data')); + try { $service = $this->getService($type); } catch (InvalidAttachmentType $e) { @@ -290,9 +286,6 @@ public function update($cardId, $attachmentId, $data, $type = 'deck_file') { } } - if ($data === false || $data === null) { - //throw new BadRequestException('data must be provided'); - } try { $attachment = $this->attachmentMapper->find($attachmentId); } catch (\Exception $e) { diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index 185e887c8..6945bbb23 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -52,6 +52,7 @@ use OCA\Deck\Db\LabelMapper; use OCP\IUserManager; use OCA\Deck\BadRequestException; +use OCA\Deck\Validators\BoardServiceValidator; use OCP\IURLGenerator; class BoardService { @@ -75,6 +76,7 @@ class BoardService { private $boardsCache = null; private $urlGenerator; + private $boardServiceValidator; public function __construct( @@ -94,6 +96,7 @@ public function __construct( IEventDispatcher $eventDispatcher, ChangeHelper $changeHelper, IURLGenerator $urlGenerator, + BoardServiceValidator $boardServiceValidator, $userId ) { $this->boardMapper = $boardMapper; @@ -113,6 +116,7 @@ public function __construct( $this->userId = $userId; $this->urlGenerator = $urlGenerator; $this->cardMapper = $cardMapper; + $this->boardServiceValidator = $boardServiceValidator; } /** @@ -177,6 +181,7 @@ public function findAll($since = -1, $details = null, $includeArchived = true) { * @throws BadRequestException */ public function find($boardId) { + $this->boardServiceValidator->check(compact('boardId')); if ($this->boardsCache && isset($this->boardsCache[$boardId])) { return $this->boardsCache[$boardId]; } @@ -231,9 +236,7 @@ private function getBoardPrerequisites() { * @throws BadRequestException */ public function isArchived($mapper, $id) { - if (is_numeric($id) === false) { - throw new BadRequestException('id must be a number'); - } + $this->boardServiceValidator->check(compact('id')); try { $boardId = $id; @@ -260,13 +263,7 @@ public function isArchived($mapper, $id) { * @throws BadRequestException */ public function isDeleted($mapper, $id) { - if ($mapper === false || $mapper === null) { - throw new BadRequestException('mapper must be provided'); - } - - if (is_numeric($id) === false) { - throw new BadRequestException('id must be a number'); - } + $this->boardServiceValidator->check(compact('mapper', 'id')); try { $boardId = $id; @@ -292,17 +289,7 @@ public function isDeleted($mapper, $id) { * @throws BadRequestException */ public function create($title, $userId, $color) { - if ($title === false || $title === null) { - throw new BadRequestException('title must be provided'); - } - - if ($userId === false || $userId === null) { - throw new BadRequestException('userId must be provided'); - } - - if ($color === false || $color === null) { - throw new BadRequestException('color must be provided'); - } + $this->boardServiceValidator->check(compact('title', 'userId', 'color')); if (!$this->permissionService->canCreate()) { throw new NoPermissionException('Creating boards has been disabled for your account.'); @@ -353,9 +340,7 @@ public function create($title, $userId, $color) { * @throws BadRequestException */ public function delete($id) { - if (is_numeric($id) === false) { - throw new BadRequestException('board id must be a number'); - } + $this->boardServiceValidator->check(compact('id')); $this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_MANAGE); $board = $this->find($id); @@ -378,9 +363,7 @@ public function delete($id) { * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException */ public function deleteUndo($id) { - if (is_numeric($id) === false) { - throw new BadRequestException('board id must be a number'); - } + $this->boardServiceValidator->check(compact('id')); $this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_MANAGE); $board = $this->find($id); @@ -401,9 +384,7 @@ public function deleteUndo($id) { * @throws BadRequestException */ public function deleteForce($id) { - if (is_numeric($id) === false) { - throw new BadRequestException('id must be a number'); - } + $this->boardServiceValidator->check(compact('id')); $this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_MANAGE); $board = $this->find($id); @@ -424,21 +405,7 @@ public function deleteForce($id) { * @throws BadRequestException */ public function update($id, $title, $color, $archived) { - if (is_numeric($id) === false) { - throw new BadRequestException('board id must be a number'); - } - - if ($title === false || $title === null) { - throw new BadRequestException('title must be provided'); - } - - if ($color === false || $color === null) { - throw new BadRequestException('color must be provided'); - } - - if (is_bool($archived) === false) { - throw new BadRequestException('archived must be a boolean'); - } + $this->boardServiceValidator->check(compact('id', 'title', 'color', 'archived')); $this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_MANAGE); $board = $this->find($id); @@ -488,29 +455,7 @@ public function enrichWithBoardSettings(Board $board) { * @throws \OCA\Deck\NoPermissionException */ public function addAcl($boardId, $type, $participant, $edit, $share, $manage) { - if (is_numeric($boardId) === false) { - throw new BadRequestException('board id must be a number'); - } - - if ($type === false || $type === null) { - throw new BadRequestException('type must be provided'); - } - - if ($participant === false || $participant === null) { - throw new BadRequestException('participant must be provided'); - } - - if ($edit === null) { - throw new BadRequestException('edit must be provided'); - } - - if ($share === null) { - throw new BadRequestException('share must be provided'); - } - - if ($manage === null) { - throw new BadRequestException('manage must be provided'); - } + $this->boardServiceValidator->check(compact('boardId', 'type', 'participant', 'edit', 'share', 'manage')); $this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_SHARE); [$edit, $share, $manage] = $this->applyPermissions($boardId, $edit, $share, $manage); @@ -556,21 +501,7 @@ public function addAcl($boardId, $type, $participant, $edit, $share, $manage) { * @throws BadRequestException */ public function updateAcl($id, $edit, $share, $manage) { - if (is_numeric($id) === false) { - throw new BadRequestException('id must be a number'); - } - - if ($edit === null) { - throw new BadRequestException('edit must be provided'); - } - - if ($share === null) { - throw new BadRequestException('share must be provided'); - } - - if ($manage === null) { - throw new BadRequestException('manage must be provided'); - } + $this->boardServiceValidator->check(compact('id', 'edit', 'share', 'manage')); $this->permissionService->checkPermission($this->aclMapper, $id, Acl::PERMISSION_SHARE); @@ -642,9 +573,7 @@ public function deleteAcl($id) { * @throws BadRequestException */ public function clone($id, $userId) { - if (is_numeric($id) === false) { - throw new BadRequestException('board id must be a number'); - } + $this->boardServiceValidator->check(compact('id', 'userId')); $this->permissionService->checkPermission($this->boardMapper, $id, Acl::PERMISSION_READ); diff --git a/lib/Service/CardService.php b/lib/Service/CardService.php index d925f67d9..8d8522790 100644 --- a/lib/Service/CardService.php +++ b/lib/Service/CardService.php @@ -43,6 +43,7 @@ use OCA\Deck\Db\LabelMapper; use OCA\Deck\StatusException; use OCA\Deck\BadRequestException; +use OCA\Deck\Validators\CardServiceValidator; use OCP\Comments\ICommentsManager; use OCP\EventDispatcher\IEventDispatcher; use OCP\IUserManager; @@ -65,6 +66,7 @@ class CardService { private $eventDispatcher; private $userManager; private $urlGenerator; + private $cardServiceValidator; public function __construct( CardMapper $cardMapper, @@ -82,6 +84,7 @@ public function __construct( ChangeHelper $changeHelper, IEventDispatcher $eventDispatcher, IURLGenerator $urlGenerator, + CardServiceValidator $cardServiceValidator, $userId ) { $this->cardMapper = $cardMapper; @@ -100,6 +103,7 @@ public function __construct( $this->eventDispatcher = $eventDispatcher; $this->currentUser = $userId; $this->urlGenerator = $urlGenerator; + $this->cardServiceValidator = $cardServiceValidator; } public function enrich($card) { @@ -122,6 +126,7 @@ public function enrich($card) { } public function fetchDeleted($boardId) { + $this->cardServiceValidator->check(compact('boardId')); $this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ); $cards = $this->cardMapper->findDeleted($boardId); foreach ($cards as $card) { @@ -187,29 +192,7 @@ public function findCalendarEntries($boardId) { * @throws BadrequestException */ public function create($title, $stackId, $type, $order, $owner, $description = '', $duedate = null) { - if ($title === 'false' || $title === null) { - throw new BadRequestException('title must be provided'); - } - - if (mb_strlen($title) > Card::TITLE_MAX_LENGTH) { - throw new BadRequestException('The title cannot exceed 255 characters'); - } - - if (is_numeric($stackId) === false) { - throw new BadRequestException('stack id must be a number'); - } - - if ($type === 'false' || $type === null) { - throw new BadRequestException('type must be provided'); - } - - if (is_numeric($order) === false) { - throw new BadRequestException('order must be a number'); - } - - if ($owner === false || $owner === null) { - throw new BadRequestException('owner must be provided'); - } + $this->cardServiceValidator->check(compact('title', 'stackId', 'type', 'order', 'owner')); $this->permissionService->checkPermission($this->stackMapper, $stackId, Acl::PERMISSION_EDIT); if ($this->boardService->isArchived($this->stackMapper, $stackId)) { @@ -279,29 +262,7 @@ public function delete($id) { * @throws BadRequestException */ public function update($id, $title, $stackId, $type, $owner, $description = '', $order = 0, $duedate = null, $deletedAt = null, $archived = null) { - if (is_numeric($id) === false) { - throw new BadRequestException('card id must be a number'); - } - - if ($title === false || $title === null) { - throw new BadRequestException('title must be provided'); - } - - if (mb_strlen($title) > Card::TITLE_MAX_LENGTH) { - throw new BadRequestException('The title cannot exceed 255 characters'); - } - - if (is_numeric($stackId) === false) { - throw new BadRequestException('stack id must be a number $$$'); - } - - if ($type === false || $type === null) { - throw new BadRequestException('type must be provided'); - } - - if ($owner === false || $owner === null) { - throw new BadRequestException('owner must be provided'); - } + $this->cardServiceValidator->check(compact('id', 'title', 'stackId', 'type', 'owner', 'order')); $this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT); $this->permissionService->checkPermission($this->stackMapper, $stackId, Acl::PERMISSION_EDIT); @@ -384,17 +345,7 @@ public function update($id, $title, $stackId, $type, $owner, $description = '', * @throws BadRequestException */ public function rename($id, $title) { - if (is_numeric($id) === false) { - throw new BadRequestException('id must be a number'); - } - - if ($title === false || $title === null) { - throw new BadRequestException('title must be provided'); - } - - if (mb_strlen($title) > Card::TITLE_MAX_LENGTH) { - throw new BadRequestException('The title cannot exceed 255 characters'); - } + $this->cardServiceValidator->check(compact('id', 'title')); $this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT); if ($this->boardService->isArchived($this->cardMapper, $id)) { @@ -425,17 +376,8 @@ public function rename($id, $title) { * @throws BadRequestException */ public function reorder($id, $stackId, $order) { - if (is_numeric($id) === false) { - throw new BadRequestException('card id must be a number'); - } - - if (is_numeric($stackId) === false) { - throw new BadRequestException('stack id must be a number'); - } + $this->cardServiceValidator->check(compact('id', 'stackId', 'order')); - if (is_numeric($order) === false) { - throw new BadRequestException('order must be a number'); - } $this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT); $this->permissionService->checkPermission($this->stackMapper, $stackId, Acl::PERMISSION_EDIT); @@ -490,9 +432,8 @@ public function reorder($id, $stackId, $order) { * @throws BadRequestException */ public function archive($id) { - if (is_numeric($id) === false) { - throw new BadRequestException('id must be a number'); - } + $this->cardServiceValidator->check(compact('id')); + $this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT); if ($this->boardService->isArchived($this->cardMapper, $id)) { @@ -520,9 +461,8 @@ public function archive($id) { * @throws BadRequestException */ public function unarchive($id) { - if (is_numeric($id) === false) { - throw new BadRequestException('id must be a number'); - } + $this->cardServiceValidator->check(compact('id')); + $this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT); if ($this->boardService->isArchived($this->cardMapper, $id)) { @@ -549,13 +489,8 @@ public function unarchive($id) { * @throws BadRequestException */ public function assignLabel($cardId, $labelId) { - if (is_numeric($cardId) === false) { - throw new BadRequestException('card id must be a number'); - } + $this->cardServiceValidator->check(compact('cardId', 'labelId')); - if (is_numeric($labelId) === false) { - throw new BadRequestException('label id must be a number'); - } $this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_EDIT); if ($this->boardService->isArchived($this->cardMapper, $cardId)) { @@ -583,13 +518,8 @@ public function assignLabel($cardId, $labelId) { * @throws BadRequestException */ public function removeLabel($cardId, $labelId) { - if (is_numeric($cardId) === false) { - throw new BadRequestException('card id must be a number'); - } + $this->cardServiceValidator->check(compact('cardId', 'labelId')); - if (is_numeric($labelId) === false) { - throw new BadRequestException('label id must be a number'); - } $this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_EDIT); if ($this->boardService->isArchived($this->cardMapper, $cardId)) { diff --git a/lib/Service/LabelService.php b/lib/Service/LabelService.php index b27384760..ffe5b8e4e 100644 --- a/lib/Service/LabelService.php +++ b/lib/Service/LabelService.php @@ -29,6 +29,7 @@ use OCA\Deck\Db\LabelMapper; use OCA\Deck\StatusException; use OCA\Deck\BadRequestException; +use OCA\Deck\Validators\LabelServiceValidator; class LabelService { @@ -40,12 +41,21 @@ class LabelService { private $boardService; /** @var ChangeHelper */ private $changeHelper; - - public function __construct(LabelMapper $labelMapper, PermissionService $permissionService, BoardService $boardService, ChangeHelper $changeHelper) { + /** @var LabelServiceValidator */ + private $labelServiceValidator; + + public function __construct( + LabelMapper $labelMapper, + PermissionService $permissionService, + BoardService $boardService, + ChangeHelper $changeHelper, + LabelServiceValidator $labelServiceValidator + ) { $this->labelMapper = $labelMapper; $this->permissionService = $permissionService; $this->boardService = $boardService; $this->changeHelper = $changeHelper; + $this->labelServiceValidator = $labelServiceValidator; } /** @@ -76,17 +86,7 @@ public function find($labelId) { * @throws BadRequestException */ public function create($title, $color, $boardId) { - if ($title === false || $title === null) { - throw new BadRequestException('title must be provided'); - } - - if ($color === false || $color === null) { - throw new BadRequestException('color must be provided'); - } - - if (is_numeric($boardId) === false) { - throw new BadRequestException('board id must be a number'); - } + $this->labelServiceValidator->check(compact('title', 'color', 'boardId')); $this->permissionService->checkPermission(null, $boardId, Acl::PERMISSION_MANAGE); @@ -121,9 +121,7 @@ public function create($title, $color, $boardId) { * @throws BadRequestException */ public function delete($id) { - if (is_numeric($id) === false) { - throw new BadRequestException('label id must be a number'); - } + $this->labelServiceValidator->check(compact('id')); $this->permissionService->checkPermission($this->labelMapper, $id, Acl::PERMISSION_MANAGE); if ($this->boardService->isArchived($this->labelMapper, $id)) { @@ -146,17 +144,7 @@ public function delete($id) { * @throws BadRequestException */ public function update($id, $title, $color) { - if (is_numeric($id) === false) { - throw new BadRequestException('label id must be a number'); - } - - if ($title === false || $title === null || $title === "") { - throw new BadRequestException('title must be provided'); - } - - if ($color === false || $color === null) { - throw new BadRequestException('color must be provided'); - } + $this->labelServiceValidator->check(compact('title', 'color', 'id')); $this->permissionService->checkPermission($this->labelMapper, $id, Acl::PERMISSION_MANAGE); diff --git a/lib/Service/StackService.php b/lib/Service/StackService.php index 0e4bbaa03..42bee9025 100644 --- a/lib/Service/StackService.php +++ b/lib/Service/StackService.php @@ -37,6 +37,7 @@ use OCA\Deck\Db\StackMapper; use OCA\Deck\NoPermissionException; use OCA\Deck\StatusException; +use OCA\Deck\Validators\StackServiceValidator; class StackService { private $stackMapper; @@ -50,6 +51,7 @@ class StackService { private $attachmentService; private $activityManager; private $changeHelper; + private $stackServiceValidator; public function __construct( StackMapper $stackMapper, @@ -62,6 +64,7 @@ public function __construct( AssignmentMapper $assignedUsersMapper, AttachmentService $attachmentService, ActivityManager $activityManager, + StackServiceValidator $stackServiceValidator, ChangeHelper $changeHelper ) { $this->stackMapper = $stackMapper; @@ -75,6 +78,7 @@ public function __construct( $this->attachmentService = $attachmentService; $this->activityManager = $activityManager; $this->changeHelper = $changeHelper; + $this->stackServiceValidator = $stackServiceValidator; } private function enrichStackWithCards($stack, $since = -1) { @@ -202,17 +206,7 @@ public function findAllArchived($boardId) { * @throws BadRequestException */ public function create($title, $boardId, $order) { - if ($title === false || $title === null) { - throw new BadRequestException('title must be provided'); - } - - if (is_numeric($order) === false) { - throw new BadRequestException('order must be a number'); - } - - if (is_numeric($boardId) === false) { - throw new BadRequestException('board id must be a number'); - } + $this->stackServiceValidator->check(compact('title', 'boardId', 'order')); $this->permissionService->checkPermission(null, $boardId, Acl::PERMISSION_MANAGE); if ($this->boardService->isArchived(null, $boardId)) { @@ -275,21 +269,7 @@ public function delete($id) { * @throws BadRequestException */ public function update($id, $title, $boardId, $order, $deletedAt) { - if (is_numeric($id) === false) { - throw new BadRequestException('stack id must be a number'); - } - - if ($title === false || $title === null) { - throw new BadRequestException('title must be provided'); - } - - if (is_numeric($boardId) === false) { - throw new BadRequestException('board id must be a number'); - } - - if (is_numeric($order) === false) { - throw new BadRequestException('order must be a number'); - } + $this->stackServiceValidator->check(compact('id', 'title', 'boardId', 'order')); $this->permissionService->checkPermission($this->stackMapper, $id, Acl::PERMISSION_MANAGE); $this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_MANAGE); @@ -325,13 +305,7 @@ public function update($id, $title, $boardId, $order, $deletedAt) { * @throws BadRequestException */ public function reorder($id, $order) { - if (is_numeric($id) === false) { - throw new BadRquestException('id must be a number'); - } - - if ($order === false || $order === null) { - throw new BadRequestException('order must be provided'); - } + $this->stackServiceValidator->check(compact('id', 'order')); $this->permissionService->checkPermission($this->stackMapper, $id, Acl::PERMISSION_MANAGE); $stackToSort = $this->stackMapper->find($id); diff --git a/lib/Validators/AssignmentServiceValidator.php b/lib/Validators/AssignmentServiceValidator.php new file mode 100644 index 000000000..42980e16b --- /dev/null +++ b/lib/Validators/AssignmentServiceValidator.php @@ -0,0 +1,37 @@ + + * + * @author Julius Härtl + * @author Maxence Lange + * @author Luka Trovic + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +declare(strict_types=1); + +namespace OCA\Deck\Validators; + +class AssignmentServiceValidator extends BaseValidator { + public function rules() { + return [ + 'cardId' => ['numeric'], + 'userId' => ['not_empty', 'not_null', 'not_false', 'max:64'], + ]; + } +} diff --git a/lib/Validators/AttachmentServiceValidator.php b/lib/Validators/AttachmentServiceValidator.php new file mode 100644 index 000000000..c3f6ae771 --- /dev/null +++ b/lib/Validators/AttachmentServiceValidator.php @@ -0,0 +1,37 @@ + + * + * @author Julius Härtl + * @author Maxence Lange + * @author Luka Trovic + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +declare(strict_types=1); + +namespace OCA\Deck\Validators; + +class AttachmentServiceValidator extends BaseValidator { + public function rules() { + return [ + 'cardId' => ['numeric'], + 'type' => ['not_empty', 'not_null', 'not_false'], + 'data' => ['not_empty', 'not_null', 'not_false', 'max:255'], + ]; + } +} diff --git a/lib/Validators/BaseValidator.php b/lib/Validators/BaseValidator.php new file mode 100644 index 000000000..5601a84a5 --- /dev/null +++ b/lib/Validators/BaseValidator.php @@ -0,0 +1,182 @@ + + * + * @author Julius Härtl + * @author Maxence Lange + * @author Luka Trovic + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +declare(strict_types=1); + +namespace OCA\Deck\Validators; + +use Exception; +use OCA\Deck\BadRequestException; + +abstract class BaseValidator { + + /** + * @return array + */ + abstract public function rules(); + + /** + * Validate given entries + * + * @param array $data + * @return void + * @throws BadRequestException + */ + private function validate($data) { + $rules = $this->rules(); + + foreach ($data as $field => $value) { + $field_rule = $rules[$field]; + + if (is_array($field_rule)) { + foreach ($field_rule as $rule) { + // The format for specifying validation rules and parameters follows an + // easy {rule}:{parameters} formatting convention. For instance the + // rule "Max:3" states that the value may only be three letters. + if (strpos($rule, ':') !== false) { + [$rule, $parameter] = explode(':', $rule, 2); + if (!$this->{$rule}($value, $parameter)) { + throw new BadRequestException( + $this->getErrorMessage($rule, $field, $parameter)); + } + } else { + if (!$this->{$rule}($value)) { + throw new BadRequestException( + $field . ' must be provided and must be '. str_replace("_", " ", $rule)); + } + } + } + } + + if (is_callable($field_rule) && !$field_rule($value)) { + throw new BadRequestException($field . ' must be provided'); + } + } + } + + /** + * @param array $data + * @return void + * @throws BadRequestException + */ + public function check(array $data) { + $this->validate($data); + } + + /** + * @param $value + * @return bool + */ + private function numeric($value): bool { + return is_numeric($value); + } + + /** + * @param $value + * @return bool + */ + private function bool($value): bool { + return is_bool($value); + } + + /** + * @param $value + * @return bool + */ + private function not_false($value): bool { + return ($value !== false) && ($value !== 'false'); + } + + /** + * @param $value + * @return bool + */ + private function not_null($value): bool { + return !is_null($value); + } + + /** + * @param $value + * @return bool + */ + private function not_empty($value): bool { + return !empty($value); + } + + /** + * @throws Exception + */ + private function max($value, $limit): bool { + if (!$limit || !is_numeric($limit)) { + throw new Exception("Validation rule max requires at least 1 parameter. " . json_encode($limit)); + } + return $this->getSize($value) <= $limit; + } + + /** + * @throws Exception + */ + private function min($value, $limit): bool { + if (!$limit || !is_numeric($limit)) { + throw new Exception("Validation rule max requires at least 1 parameter."); + } + return $this->getSize($value) >= $limit; + } + + /** + * Get the size of an attribute. + * + * @param mixed $value + * @return int + */ + protected function getSize($value): int { + // This method will determine if the attribute is a number or string and + // return the proper size accordingly. If it is a number, then number itself + // is the size. + if (is_int($value)) { + return $value; + } elseif (is_array($value)) { + return count($value); + } + + return mb_strlen($value ?? ''); + } + + /** + * @param $rule + * @param $field + * @param $parameter + * @return string + */ + protected function getErrorMessage($rule, $field, $parameter = null): string { + if (in_array($rule, ['max', 'min'])) { + return $rule === 'max' + ? $field . ' cannot be longer than '. $parameter . ' characters ' + : $field . ' must be at least '. $parameter . ' characters long '; + } + + return $field . ' must be provided and must be '. str_replace("_", " ", $rule); + } +} diff --git a/lib/Validators/BoardServiceValidator.php b/lib/Validators/BoardServiceValidator.php new file mode 100644 index 000000000..f5d58ecb0 --- /dev/null +++ b/lib/Validators/BoardServiceValidator.php @@ -0,0 +1,47 @@ + + * + * @author Julius Härtl + * @author Maxence Lange + * @author Luka Trovic + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +declare(strict_types=1); + +namespace OCA\Deck\Validators; + +class BoardServiceValidator extends BaseValidator { + public function rules() { + return [ + 'id' => ['numeric'], + 'boardId' => ['numeric'], + 'type' => ['numeric'], + 'mapper' => ['not_empty', 'not_null', 'not_false'], + 'title' => ['not_empty', 'not_null', 'not_false', 'max:100'], + 'userId' => ['not_empty', 'not_null', 'not_false', 'max:64'], + 'color' => ['not_empty', 'not_null', 'not_false', 'max:6'], + 'participant' => ['not_empty', 'not_null', 'not_false', 'max:64'], + 'edit' => ['not_null'], + 'share' => ['not_null'], + 'manage' => ['not_null'], + 'archived' => ['bool'] + ]; + } +} diff --git a/lib/Validators/CardServiceValidator.php b/lib/Validators/CardServiceValidator.php new file mode 100644 index 000000000..0417d996c --- /dev/null +++ b/lib/Validators/CardServiceValidator.php @@ -0,0 +1,44 @@ + + * + * @author Julius Härtl + * @author Maxence Lange + * @author Luka Trovic + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +declare(strict_types=1); + +namespace OCA\Deck\Validators; + +class CardServiceValidator extends BaseValidator { + public function rules() { + return [ + 'id' => ['numeric'], + 'title' => ['not_empty', 'not_null', 'not_false', 'max:255'], + 'cardId' => ['numeric'], + 'stackId' => ['numeric'], + 'boardId' => ['numeric'], + 'labelId' => ['numeric'], + 'type' => ['not_empty', 'not_null', 'not_false', 'max:64'], + 'order' => ['numeric'], + 'owner' => ['not_empty', 'not_null', 'not_false', 'max:64'], + ]; + } +} diff --git a/lib/Validators/LabelServiceValidator.php b/lib/Validators/LabelServiceValidator.php new file mode 100644 index 000000000..c350cb769 --- /dev/null +++ b/lib/Validators/LabelServiceValidator.php @@ -0,0 +1,39 @@ + + * + * @author Julius Härtl + * @author Maxence Lange + * @author Luka Trovic + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + + declare(strict_types=1); + +namespace OCA\Deck\Validators; + +class LabelServiceValidator extends BaseValidator { + public function rules() { + return [ + 'id' => ['numeric'], + 'title' => ['not_empty', 'not_null', 'not_false', 'max:100'], + 'boardId' => ['numeric', 'not_null'], + 'color' => ['not_empty', 'not_null', 'not_false', 'max:6'] + ]; + } +} diff --git a/lib/Validators/StackServiceValidator.php b/lib/Validators/StackServiceValidator.php new file mode 100644 index 000000000..c32e7ac7f --- /dev/null +++ b/lib/Validators/StackServiceValidator.php @@ -0,0 +1,39 @@ + + * + * @author Julius Härtl + * @author Maxence Lange + * @author Luka Trovic + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +declare(strict_types=1); + +namespace OCA\Deck\Validators; + +class StackServiceValidator extends BaseValidator { + public function rules() { + return [ + 'id' => ['numeric'], + 'title' => ['not_empty', 'not_null', 'not_false', 'max:100'], + 'boardId' => ['numeric', 'not_null'], + 'order' => ['numeric', 'not_null'] + ]; + } +} diff --git a/src/components/navigation/AppNavigationAddBoard.vue b/src/components/navigation/AppNavigationAddBoard.vue index ad7b66c4c..ef7c555a6 100644 --- a/src/components/navigation/AppNavigationAddBoard.vue +++ b/src/components/navigation/AppNavigationAddBoard.vue @@ -70,9 +70,9 @@ export default { startCreateBoard(e) { this.editing = true }, - createBoard(e) { + async createBoard(e) { const title = e.currentTarget.childNodes[0].value - this.$store.dispatch('createBoard', { + await this.$store.dispatch('createBoard', { title, color: this.color.substring(1), }) diff --git a/src/store/main.js b/src/store/main.js index ffc859c63..0d5e35ea0 100644 --- a/src/store/main.js +++ b/src/store/main.js @@ -392,11 +392,13 @@ export default new Vuex.Store({ const storedBoard = await apiClient.updateBoard(board) commit('addBoard', storedBoard) }, - createBoard({ commit }, boardData) { - apiClient.createBoard(boardData) - .then((board) => { - commit('addBoard', board) - }) + async createBoard({ commit }, boardData) { + try { + const board = await apiClient.createBoard(boardData) + commit('addBoard', board) + } catch (err) { + return err + } }, async cloneBoard({ commit }, boardData) { try { diff --git a/tests/integration/features/decks.feature b/tests/integration/features/decks.feature index bb141ef7d..22a74baec 100644 --- a/tests/integration/features/decks.feature +++ b/tests/integration/features/decks.feature @@ -13,3 +13,22 @@ Feature: decks |key|value| |title|MyBoard| |color|000000| + + Scenario: Fail to create a board with invalid parameters + Given acting as user "user0" + When creates a board named "This is a very ong name that exceeds the maximum length of a deck board created which is longer than 100 characters" with color "ff0000" + Then the response should have a status code 400 + When creates a board named "Example board" with color "invalid" + Then the response should have a status code 400 + + Scenario: Fail to create a list with invalid parameters + Given acting as user "user0" + And creates a board named "MyBoard" with color "000000" + When create a stack named "This is a very ong name that exceeds the maximum length of a deck board created which is longer than 100 characters" + Then the response should have a status code 400 + + Scenario: Fail to create a card with invalid parameters + Given acting as user "user0" + And creates a board named "MyBoard" with color "000000" + And create a stack named "ToDo" + When create a card named "This is a very ong name that exceeds the maximum length of a deck board created which is longer than 255 characters This is a very ong name that exceeds the maximum length of a deck board created which is longer than 255 characters This is a very ong name that exceeds the maximum length of a deck board created which is longer than 255 characters" diff --git a/tests/unit/Service/AssignmentServiceTest.php b/tests/unit/Service/AssignmentServiceTest.php index 56414c54a..5c83a10d9 100644 --- a/tests/unit/Service/AssignmentServiceTest.php +++ b/tests/unit/Service/AssignmentServiceTest.php @@ -32,6 +32,7 @@ use OCA\Deck\Db\ChangeHelper; use OCA\Deck\NotFoundException; use OCA\Deck\Notification\NotificationHelper; +use OCA\Deck\Validators\AssignmentServiceValidator; use OCP\Activity\IEvent; use OCP\EventDispatcher\IEventDispatcher; use PHPUnit\Framework\MockObject\MockObject; @@ -76,6 +77,11 @@ class AssignmentServiceTest extends TestCase { * @var AssignmentService */ private $assignmentService; + /** + * @var AssignmentServiceValidator + */ + private $assignmentServiceValidator; + public function setUp(): void { parent::setUp(); @@ -87,6 +93,7 @@ public function setUp(): void { $this->activityManager = $this->createMock(ActivityManager::class); $this->eventDispatcher = $this->createMock(IEventDispatcher::class); $this->changeHelper = $this->createMock(ChangeHelper::class); + $this->assignmentServiceValidator = $this->createMock(AssignmentServiceValidator::class); $this->assignmentService = new AssignmentService( $this->permissionService, $this->cardMapper, @@ -96,6 +103,7 @@ public function setUp(): void { $this->activityManager, $this->changeHelper, $this->eventDispatcher, + $this->assignmentServiceValidator, 'admin' ); } diff --git a/tests/unit/Service/AttachmentServiceTest.php b/tests/unit/Service/AttachmentServiceTest.php index 7e26bcef4..118feedfd 100644 --- a/tests/unit/Service/AttachmentServiceTest.php +++ b/tests/unit/Service/AttachmentServiceTest.php @@ -34,6 +34,7 @@ use OCA\Deck\InvalidAttachmentType; use OCA\Deck\NoPermissionException; use OCA\Deck\NotFoundException; +use OCA\Deck\Validators\AttachmentServiceValidator; use OCP\AppFramework\Http\Response; use OCP\AppFramework\IAppContainer; use OCP\IL10N; @@ -86,6 +87,10 @@ class AttachmentServiceTest extends TestCase { * @var IAttachmentService|MockObject */ private $filesAppServiceImpl; + /** + * @var AttachmentServiceValidator + */ + private $attachmentServiceValidator; /** * @throws \OCP\AppFramework\QueryException @@ -122,6 +127,7 @@ public function setUp(): void { $this->l10n = $this->createMock(IL10N::class); $this->changeHelper = $this->createMock(ChangeHelper::class); + $this->attachmentServiceValidator = $this->createMock(AttachmentServiceValidator::class); $this->attachmentService = new AttachmentService( $this->attachmentMapper, @@ -132,7 +138,8 @@ public function setUp(): void { $this->attachmentCacheHelper, $this->userId, $this->l10n, - $this->activityManager + $this->activityManager, + $this->attachmentServiceValidator ); } @@ -158,7 +165,7 @@ public function testRegisterAttachmentService() { $application->expects($this->any()) ->method('getContainer') ->willReturn($appContainer); - $attachmentService = new AttachmentService($this->attachmentMapper, $this->cardMapper, $this->changeHelper, $this->permissionService, $application, $this->attachmentCacheHelper, $this->userId, $this->l10n, $this->activityManager); + $attachmentService = new AttachmentService($this->attachmentMapper, $this->cardMapper, $this->changeHelper, $this->permissionService, $application, $this->attachmentCacheHelper, $this->userId, $this->l10n, $this->activityManager, $this->attachmentServiceValidator); $attachmentService->registerAttachmentService('custom', MyAttachmentService::class); $this->assertEquals($fileServiceMock, $attachmentService->getService('deck_file')); $this->assertEquals(MyAttachmentService::class, get_class($attachmentService->getService('custom'))); @@ -188,7 +195,7 @@ public function testRegisterAttachmentServiceNotExisting() { ->method('getContainer') ->willReturn($appContainer); - $attachmentService = new AttachmentService($this->attachmentMapper, $this->cardMapper, $this->changeHelper, $this->permissionService, $application, $this->attachmentCacheHelper, $this->userId, $this->l10n, $this->activityManager); + $attachmentService = new AttachmentService($this->attachmentMapper, $this->cardMapper, $this->changeHelper, $this->permissionService, $application, $this->attachmentCacheHelper, $this->userId, $this->l10n, $this->activityManager, $this->attachmentServiceValidator); $attachmentService->registerAttachmentService('custom', MyAttachmentService::class); $attachmentService->getService('deck_file_invalid'); } diff --git a/tests/unit/Service/BoardServiceTest.php b/tests/unit/Service/BoardServiceTest.php index 0dcc4ec50..571167b22 100644 --- a/tests/unit/Service/BoardServiceTest.php +++ b/tests/unit/Service/BoardServiceTest.php @@ -44,6 +44,7 @@ use OCP\IGroupManager; use \Test\TestCase; use OCP\IURLGenerator; +use OCA\Deck\Validators\BoardServiceValidator; class BoardServiceTest extends TestCase { @@ -80,6 +81,8 @@ class BoardServiceTest extends TestCase { private $userId = 'admin'; /** @var IURLGenerator */ private $urlGenerator; + /** @var BoardServiceValidator */ + private $boardServiceValidator; public function setUp(): void { parent::setUp(); @@ -99,6 +102,7 @@ public function setUp(): void { $this->changeHelper = $this->createMock(ChangeHelper::class); $this->eventDispatcher = $this->createMock(IEventDispatcher::class); $this->urlGenerator = $this->createMock(IURLGenerator::class); + $this->boardServiceValidator = $this->createMock(BoardServiceValidator::class); $this->service = new BoardService( $this->boardMapper, @@ -117,6 +121,7 @@ public function setUp(): void { $this->eventDispatcher, $this->changeHelper, $this->urlGenerator, + $this->boardServiceValidator, $this->userId ); diff --git a/tests/unit/Service/CardServiceTest.php b/tests/unit/Service/CardServiceTest.php index 622b22c5b..3f2a63676 100644 --- a/tests/unit/Service/CardServiceTest.php +++ b/tests/unit/Service/CardServiceTest.php @@ -35,6 +35,7 @@ use OCA\Deck\Db\LabelMapper; use OCA\Deck\Notification\NotificationHelper; use OCA\Deck\StatusException; +use OCA\Deck\Validators\CardServiceValidator; use OCP\Activity\IEvent; use OCP\Comments\ICommentsManager; use OCP\EventDispatcher\IEventDispatcher; @@ -79,6 +80,8 @@ class CardServiceTest extends TestCase { /** @var IURLGenerator|MockObject */ private $urlGenerator; + /** @var CardServiceValidator|MockObject */ + private $cardServiceValidator; public function setUp(): void { parent::setUp(); @@ -97,6 +100,8 @@ public function setUp(): void { $this->eventDispatcher = $this->createMock(IEventDispatcher::class); $this->changeHelper = $this->createMock(ChangeHelper::class); $this->urlGenerator = $this->createMock(IURLGenerator::class); + $this->cardServiceValidator = $this->createMock(CardServiceValidator::class); + $this->cardService = new CardService( $this->cardMapper, $this->stackMapper, @@ -113,6 +118,7 @@ public function setUp(): void { $this->changeHelper, $this->eventDispatcher, $this->urlGenerator, + $this->cardServiceValidator, 'user1' ); } diff --git a/tests/unit/Service/LabelServiceTest.php b/tests/unit/Service/LabelServiceTest.php index 52cc36e4b..79c192aaf 100644 --- a/tests/unit/Service/LabelServiceTest.php +++ b/tests/unit/Service/LabelServiceTest.php @@ -26,6 +26,7 @@ use OCA\Deck\Db\ChangeHelper; use OCA\Deck\Db\Label; use OCA\Deck\Db\LabelMapper; +use OCA\Deck\Validators\LabelServiceValidator; use Test\TestCase; class LabelServiceTest extends TestCase { @@ -40,6 +41,8 @@ class LabelServiceTest extends TestCase { private $boardService; /** @var ChangeHelper|\PHPUnit\Framework\MockObject\MockObject */ private $changeHelper; + /** @var LabelServiceValidator\MockObject */ + private $labelServiceValidator; public function setUp(): void { parent::setUp(); @@ -49,11 +52,14 @@ public function setUp(): void { ->disableOriginalConstructor()->getMock(); $this->boardService = $this->createMock(BoardService::class); $this->changeHelper = $this->createMock(ChangeHelper::class); + $this->labelServiceValidator = $this->createMock(LabelServiceValidator::class); + $this->labelService = new LabelService( $this->labelMapper, $this->permissionService, $this->boardService, - $this->changeHelper + $this->changeHelper, + $this->labelServiceValidator, ); } diff --git a/tests/unit/Service/StackServiceTest.php b/tests/unit/Service/StackServiceTest.php index 913a74f69..7c242a384 100644 --- a/tests/unit/Service/StackServiceTest.php +++ b/tests/unit/Service/StackServiceTest.php @@ -33,6 +33,7 @@ use OCA\Deck\Db\LabelMapper; use OCA\Deck\Db\Stack; use OCA\Deck\Db\StackMapper; +use OCA\Deck\Validators\StackServiceValidator; use \Test\TestCase; /** @@ -67,6 +68,8 @@ class StackServiceTest extends TestCase { private $activityManager; /** @var ChangeHelper|\PHPUnit\Framework\MockObject\MockObject */ private $changeHelper; + /** @var StackServiceValidator|\PHPUnit\Framework\MockObject\MockObject */ + private $stackServiceValidator; public function setUp(): void { parent::setUp(); @@ -81,6 +84,7 @@ public function setUp(): void { $this->labelMapper = $this->createMock(LabelMapper::class); $this->activityManager = $this->createMock(ActivityManager::class); $this->changeHelper = $this->createMock(ChangeHelper::class); + $this->stackServiceValidator = $this->createMock(StackServiceValidator::class); $this->stackService = new StackService( $this->stackMapper, @@ -93,6 +97,7 @@ public function setUp(): void { $this->assignedUsersMapper, $this->attachmentService, $this->activityManager, + $this->stackServiceValidator, $this->changeHelper ); } diff --git a/tests/unit/Validators/StackServiceValidatorTest.php b/tests/unit/Validators/StackServiceValidatorTest.php new file mode 100644 index 000000000..052f79724 --- /dev/null +++ b/tests/unit/Validators/StackServiceValidatorTest.php @@ -0,0 +1,77 @@ + + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + + +namespace OCA\Deck\Validators; + +use OCA\Deck\Tests\unit\Validators\ValidatorTestBase; + +class StackServiceValidatorTest extends ValidatorTestBase { + public function setUp(): void { + parent::setUpValidatorTest(StackServiceValidator::class); + } + + public function testTitle() { + $this->assertPass([ + 'title' => 'Short title', + ]); + $this->assertPass([ + 'title' => str_repeat('A', 100) + ]); + $this->assertFail([ + 'title' => str_repeat('A', 101) + ]); + $this->assertFail([ + 'title' => '', + ]); + $this->assertFail([ + 'title' => null, + ]); + } + + public function testId() { + $this->assertPass([ 'id' => 1234 ]); + $this->assertPass([ 'id' => '1234' ]); + $this->assertFail([ 'id' => 'a1234' ]); + $this->assertFail([ 'id' => '' ]); + $this->assertFail([ 'id' => null ]); + } + + public function testBoardId() { + $this->assertPass([ 'boardId' => 1234 ]); + $this->assertPass([ 'boardId' => '1234' ]); + $this->assertFail([ 'boardId' => 'a1234' ]); + $this->assertFail([ 'boardId' => '' ]); + $this->assertFail([ 'boardId' => null ]); + } + + public function testOrder() { + $this->assertPass([ 'order' => 1234 ]); + $this->assertPass([ 'order' => '1234' ]); + $this->assertFail([ 'order' => 'a1234' ]); + $this->assertFail([ 'order' => '' ]); + $this->assertFail([ 'order' => null ]); + } +} diff --git a/tests/unit/Validators/ValidatorTestBase.php b/tests/unit/Validators/ValidatorTestBase.php new file mode 100644 index 000000000..81f1cc76e --- /dev/null +++ b/tests/unit/Validators/ValidatorTestBase.php @@ -0,0 +1,58 @@ + + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + + +namespace OCA\Deck\Tests\unit\Validators; + +use OCA\Deck\BadRequestException; +use OCA\Deck\Validators\BaseValidator; + +abstract class ValidatorTestBase extends \PHPUnit\Framework\TestCase { + /** @var BaseValidator */ + protected $validator; + + public function setUpValidatorTest($class = null): void { + parent::setUp(); + + $this->validator = new $class(); + } + + protected function assertPass($values) { + self::assertTrue($this->check($values)); + } + + protected function assertFail($values) { + self::assertFalse($this->check($values)); + } + + private function check($values) { + try { + $this->validator->check($values); + return true; + } catch (BadRequestException $e) { + return false; + } + } +}