From b81c628faa1ac936f35c1efac54464d5ab962180 Mon Sep 17 00:00:00 2001 From: Guillermo Giuliana Date: Sun, 10 Nov 2019 16:14:30 -0300 Subject: [PATCH 01/19] Search ticket path backend --- server/controllers/staff/get-new-tickets.php | 2 +- server/controllers/ticket.php | 1 + server/controllers/ticket/search.php | 290 ++++++++++++++++++ server/data/ERRORS.php | 9 + server/libs/validations/validAuthorsId.php | 23 ++ server/libs/validations/validDateRange.php | 21 ++ .../libs/validations/validDepartmentsId.php | 20 ++ server/libs/validations/validOrderBy.php | 22 ++ server/libs/validations/validPrioritys.php | 19 ++ server/libs/validations/validTagsId.php | 20 ++ 10 files changed, 426 insertions(+), 1 deletion(-) create mode 100644 server/controllers/ticket/search.php create mode 100644 server/libs/validations/validAuthorsId.php create mode 100644 server/libs/validations/validDateRange.php create mode 100644 server/libs/validations/validDepartmentsId.php create mode 100644 server/libs/validations/validOrderBy.php create mode 100644 server/libs/validations/validPrioritys.php create mode 100644 server/libs/validations/validTagsId.php diff --git a/server/controllers/staff/get-new-tickets.php b/server/controllers/staff/get-new-tickets.php index e9986740..9407ee54 100755 --- a/server/controllers/staff/get-new-tickets.php +++ b/server/controllers/staff/get-new-tickets.php @@ -32,7 +32,7 @@ class GetNewTicketsStaffController extends Controller { public function validations() { return[ - 'permission' => 'staff_1', + 'permission' => 'any', 'requestData' => [ 'page' => [ 'validation' => DataValidator::numeric(), diff --git a/server/controllers/ticket.php b/server/controllers/ticket.php index 5afbf8d5..e60c253e 100755 --- a/server/controllers/ticket.php +++ b/server/controllers/ticket.php @@ -23,5 +23,6 @@ $ticketControllers->addController(new DeleteTagController); $ticketControllers->addController(new GetTagsController); $ticketControllers->addController(new AddTagController); $ticketControllers->addController(new RemoveTagController); +$ticketControllers->addController(new SearchController); $ticketControllers->finalize(); diff --git a/server/controllers/ticket/search.php b/server/controllers/ticket/search.php new file mode 100644 index 00000000..b4c86a08 --- /dev/null +++ b/server/controllers/ticket/search.php @@ -0,0 +1,290 @@ + 'any', + 'requestData' => [ + 'page' => [ + 'validation' => DataValidator::oneOf(DataValidator::numeric()->positive(),DataValidator::nullType()), + 'error' => ERRORS::INVALID_PAGE + ], + 'tags' => [ + 'validation' => DataValidator::oneOf(DataValidator::validTagsId(),DataValidator::nullType()), + 'error' => ERRORS::INVALID_TAG_FILTER + ], + 'closed' => [ + 'validation' => DataValidator::oneOf(DataValidator::in(['0','1']),DataValidator::nullType()), + 'error' => ERRORS::INVALID_CLOSED_FILTER + ], + 'unreadStaff' => [ + 'validation' => DataValidator::oneOf(DataValidator::in(['0','1']),DataValidator::nullType()), + 'error' => ERRORS::INVALID_UNREAD_STAFF_FILTER + ], + 'priority' => [ + 'validation' => DataValidator::oneOf(DataValidator::validPrioritys(),DataValidator::nullType()), + 'error' => ERRORS::INVALID_PRIORITY_FILTER + ], + 'dateRange' => [ + 'validation' => DataValidator::oneOf(DataValidator::validDateRange(),DataValidator::nullType()), + 'error' => ERRORS::INVALID_DATE_RANGE_FILTER + ], + 'departments' => [ + 'validation' => DataValidator::oneOf(DataValidator::validDepartmentsId(),DataValidator::nullType()), + 'error' => ERRORS::INVALID_DEPARTMENT_FILTER + ], + 'authors' => [ + 'validation' => DataValidator::oneOf(DataValidator::validAuthorsId(),DataValidator::nullType()), + 'error' => ERRORS::INVALID_AUTHOR_FILTER + ], + 'assigned' => [ + 'validation' => DataValidator::oneOf(DataValidator::in(['0','1']),DataValidator::nullType()), + 'error' => ERRORS::INVALID_ASSIGNED_FILTER + ], + 'orderBy' => [ + 'validation' => DataValidator::oneOf(DataValidator::ValidOrderBy(),DataValidator::nullType()), + 'error' => ERRORS::INVALID_ORDER_BY + ], + ] + ]; + } + + public function handler() { + $query = "FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id)"; + $filters = ""; + $order = ""; + Controller::request("page") ? $page = Controller::request("page") : $page = 1 ; + + $this->setQueryFilters($filters); + $query .= $filters . " GROUP BY ticket.id"; + + $totalCount = RedBean::getAll("SELECT COUNT(*) FROM (SELECT COUNT(*) " . $query . " ) AS T2")[0]['COUNT(*)']; + error_log(print_r("SELECT COUNT(*) FROM (SELECT COUNT(*) " . $query . " ) AS T2", true)); + error_log(print_r($totalCount, true)); + + $query = "SELECT ticket.id,ticket.title,ticket.ticket_number,ticket.content ,ticketevent.content " . $query; + + $this->setQueryOrder($order); + $query .= $order ." LIMIT 10 OFFSET " . (($page-1)*10); + + $ticketList = RedBean::getAll($query); + + Response::respondSuccess([ + 'tickets' => $ticketList, + 'pages' => ceil($totalCount / 10), + 'page' => Controller::request('page') + ]); + + } + //FILTER + private function setQueryFilters(&$filters){ + $this->setTagFilter($filters); + $this->setClosedFilter($filters); + $this->setAssignedFilter($filters); + $this->setSeenFilter($filters); + $this->setPriorityFilter($filters); + $this->setDateFilter($filters); + $this->setDepartmentFilter($filters); + $this->setAuthorFilter($filters); + $this->setStringFilter($filters); + + if($filters != "") $filters = " WHERE " . $filters; + } + + private function setTagFilter(&$filters){ + $tagList = json_decode(Controller::request('tags')); + + if($tagList){ + $filters != "" ? $filters .= " and " : null; + + foreach($tagList as $key => $tag) { + + $key == 0 ? $filters .= " ( " : null; + ($key != 0 && $key != sizeof($tagList)) ? $filters .= " or " : null; + + $filters .= "tag_ticket.tag_id = " . $tag ; + } + $filters .= ")"; + } + } + private function setClosedFilter(&$filters){ + $closed = Controller::request('closed'); + + if ($closed != null) { + if ($filters != "") $filters .= " and "; + $filters .= "ticket.closed = " . $closed ; + } + } + private function setSeenFilter(&$filters){ + $unreadStaff = Controller::request('unreadStaff'); + if ($unreadStaff != null) { + if ($filters != "") $filters .= " and "; + $filters .= "ticket.unread_staff = " . $unreadStaff; + } + } + private function setPriorityFilter(&$filters){ + $prioritys = json_decode(Controller::request('priority')); + if($prioritys != null){ + if ($filters != "") $filters .= " and "; + foreach(array_unique($prioritys) as $key => $priority) { + + $key == 0 ? $filters .= " ( " : null; + ($key != 0 && $key != sizeof($prioritys)) ? $filters .= " or " : null; + + if($priority == 0){ + $filters .= "ticket.priority = " . "'low'"; + }elseif($priority == 1){ + $filters .= "ticket.priority = " . "'medium'"; + }elseif($priority == 2){ + $filters .= "ticket.priority = " . "'high'"; + } + + $key == sizeof($prioritys) ? $filters .= " ) " : null ; + } + $prioritys != "" ? $filters .= ") " : null; + } + } + + private function setDateFilter(&$filters){ + $dateRange = json_decode(Controller::request('dateRange')); + if ($dateRange != null) { + if ($filters != "") $filters .= " and "; + + foreach($dateRange as $key => $date) { + $key == 0 ? ($filters .= "(ticket.date >= " . $date ): ($filters .= " and ticket.date <= " . $date . ")"); + } + } + } + + private function setDepartmentFilter(&$filters){ + + $departments = json_decode(Controller::request('departments')); + + if($departments != null){ + if ($filters != "") $filters .= " and "; + + foreach($departments as $key => $department) { + + $key == 0 ? $filters .= " ( " : null; + ($key != 0 && $key != sizeof($departments)) ? $filters .= " or " : null; + + $filters .= "ticket.department_id = " . $department ; + } + $filters .= ")"; + } + } + + private function setAuthorFilter(&$filters){ + $authors = json_decode(Controller::request('authors')); + + if($authors != null){ + + if ($filters != "") $filters .= " and "; + + foreach($authors as $key => $author){ + + $key == 0 ? $filters .= " ( " : null; + ($key != 0 && $key != sizeof($authors)) ? $filters .= " or " : null; + + if($author->staff){ + $filters .= "ticket.author_staff_id = " . $author->id; + } else { + $filters .= "ticket.author_id = " . $author->id; + } + } + + $filters .= ")"; + + } + } + + private function setAssignedFilter(&$filters){ + $assigned = Controller::request('assigned'); + if($assigned != null){ + if ($filters != "") $filters .= " and "; + $key = ""; + $assigned == 0 ? $key = "IS NULL" : $key = "IS NOT NULL"; + $filters .= "ticket.owner_id " . $key; + } + } + + private function setStringFilter(&$filters){ + $string = Controller::request('query'); + if($string != null){ + if ($filters != "") $filters .= " and "; + $filters .= " (ticket.title LIKE '%" . $string . "%' or ticket.content LIKE '%" . $string . "%' or ticket.ticket_number LIKE '%" . $string . "%' or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%" . $string ."%'))"; + }; + } + + //ORDER + private function setQueryOrder(&$order){ + $order = " ORDER BY "; + $this->setStringOrder($order); + $this->setEspecificOrder($order); + $order .= "ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.priority desc, ticket.date desc "; + } + private function setEspecificOrder(&$order){ + $orderBy = json_decode(Controller::request('orderBy')); + if($orderBy != null){ + $orientation = ($orderBy->asc ? " asc" : " desc" ); + $order .= "ticket." . $orderBy->value . $orientation . ","; + }; + } + private function setStringOrder(&$order){ + $string = Controller::request('query'); + if($string != null){ + $order .= "CASE WHEN (ticket.ticket_number LIKE '%" . $string ."%') THEN ticket.ticket_number END desc,CASE WHEN (ticket.title LIKE '%" . $string ."%') THEN ticket.title END desc, CASE WHEN ( ticket.content LIKE '%" . $string ."%') THEN ticket.content END desc, CASE WHEN (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%".$string."%') THEN ticketevent.content END desc," ; + } + } + +} + diff --git a/server/data/ERRORS.php b/server/data/ERRORS.php index 831086a9..2e56b685 100755 --- a/server/data/ERRORS.php +++ b/server/data/ERRORS.php @@ -277,6 +277,15 @@ class ERRORS { const INVALID_PRIORITY = 'INVALID_PRIORITY'; const INVALID_PAGE = 'INVALID_PAGE'; const INVALID_QUERY = 'INVALID_QUERY'; + const INVALID_TAG_FILTER = 'INVALID_TAG_FILTER'; + const INVALID_CLOSED_FILTER = 'INVALID_CLOSED_FILTER'; + const INVALID_UNREAD_STAFF_FILTER = 'INVALID_UNREAD_STAFF_FILTER'; + const INVALID_PRIORITY_FILTER = 'INVALID_PRIORITY_FILTER'; + const INVALID_DATE_RANGE_FILTER = 'INVALID_DATE_RANGE_FILTER'; + const INVALID_DEPARTMENT_FILTER = 'INVALID_DEPARTMENT_FILTER'; + const INVALID_AUTHOR_FILTER = 'INVALID_AUTHOR_FILTER'; + const INVALID_ASSIGNED_FILTER = 'INVALID_ASSIGNED_FILTER'; + const INVALID_ORDER_BY = 'INVALID_ORDER_BY'; const INVALID_TOPIC = 'INVALID_TOPIC'; const INVALID_SEARCH = 'INVALID_SEARCH'; const INVALID_ORDER = 'INVALID_ORDER'; diff --git a/server/libs/validations/validAuthorsId.php b/server/libs/validations/validAuthorsId.php new file mode 100644 index 00000000..3cda8229 --- /dev/null +++ b/server/libs/validations/validAuthorsId.php @@ -0,0 +1,23 @@ +staff){ + $author = \Staff::getDataStore($authorObject->id); + }else{ + $author = \User::getDataStore($authorObject->id); + } + if($author->isNull()) return false; + } + return true; + } + return false; + } +} \ No newline at end of file diff --git a/server/libs/validations/validDateRange.php b/server/libs/validations/validDateRange.php new file mode 100644 index 00000000..05f6a3c2 --- /dev/null +++ b/server/libs/validations/validDateRange.php @@ -0,0 +1,21 @@ +isNull()) return false; + } + return true; + } + return false; + } +} \ No newline at end of file diff --git a/server/libs/validations/validOrderBy.php b/server/libs/validations/validOrderBy.php new file mode 100644 index 00000000..4fed26c1 --- /dev/null +++ b/server/libs/validations/validOrderBy.php @@ -0,0 +1,22 @@ +asc !== true && $object->asc !== false) return false; + + foreach ($values as $value) { + if($object->value == $value) $isTrue = true; + } + return $isTrue; + } + } +} \ No newline at end of file diff --git a/server/libs/validations/validPrioritys.php b/server/libs/validations/validPrioritys.php new file mode 100644 index 00000000..53bf9505 --- /dev/null +++ b/server/libs/validations/validPrioritys.php @@ -0,0 +1,19 @@ +isNull()) return false; + } + return true; + } + return false; + } +} \ No newline at end of file From 57d3766c9d84bbf1a9ca6ff90ab682f0caabead7 Mon Sep 17 00:00:00 2001 From: Guillermo Date: Thu, 14 Nov 2019 17:17:45 -0300 Subject: [PATCH 02/19] unit test for Search ticket --- server/controllers/staff/get-new-tickets.php | 2 +- server/controllers/ticket/search.php | 165 +++++++++--------- server/libs/validations/validOrderBy.php | 10 +- server/tests/__mocks__/ControllerMock.php | 10 +- server/tests/controllers/user/loginTest.php | 2 +- .../libs/LinearCongruentialGeneratorTest.php | 1 + tests/staff/get-all.rb | 8 +- tests/ticket/search.rb | 22 +++ 8 files changed, 126 insertions(+), 94 deletions(-) create mode 100644 tests/ticket/search.rb diff --git a/server/controllers/staff/get-new-tickets.php b/server/controllers/staff/get-new-tickets.php index 9407ee54..e9986740 100755 --- a/server/controllers/staff/get-new-tickets.php +++ b/server/controllers/staff/get-new-tickets.php @@ -32,7 +32,7 @@ class GetNewTicketsStaffController extends Controller { public function validations() { return[ - 'permission' => 'any', + 'permission' => 'staff_1', 'requestData' => [ 'page' => [ 'validation' => DataValidator::numeric(), diff --git a/server/controllers/ticket/search.php b/server/controllers/ticket/search.php index b4c86a08..0f9f9f1e 100644 --- a/server/controllers/ticket/search.php +++ b/server/controllers/ticket/search.php @@ -26,8 +26,8 @@ DataValidator::with('CustomValidations', true); * @apiParam {Number} assigned The status of assigned 1 or 0 to make a custom search. * @apiParam {String} query A string to find into a ticket to make a custom search. * @apiParam {Number} page The number of the page of the tickets. - * @apiParam {Object} orderBy A object {value, asc}with string and boolean to make a especific order of the search. - * + * @apiParam {Object} orderBy A object {value, asc}with string and boolean to make a especific order of the search. + * * @apiUse NO_PERMISSION * @apiUse INVALID_TAG_FILTER * @apiUse INVALID_CLOSED_FILTER @@ -99,24 +99,25 @@ class SearchController extends Controller { } public function handler() { - $query = "FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id)"; - $filters = ""; - $order = ""; - Controller::request("page") ? $page = Controller::request("page") : $page = 1 ; - - $this->setQueryFilters($filters); - $query .= $filters . " GROUP BY ticket.id"; + $inputs = [ + 'closed' => Controller::request('closed'), + 'tags' => json_decode(Controller::request('tags')), + 'unreadStaff' => Controller::request('unreadStaff'), + 'priority' => json_decode(Controller::request('priority')), + 'dateRange' => json_decode(Controller::request('dateRange')), + 'departments' => json_decode(Controller::request('departments')), + 'authors' => json_decode(Controller::request('authors'),true), + 'assigned' => Controller::request('assigned'), + 'query' => Controller::request('query'), + 'orderBy' => json_decode(Controller::request('orderBy'),true), + 'page' => Controller::request('page') + ]; + $query = $this->getSQLQuery($inputs); + $queryWithOrder = $this->getSQLQueryWithOrder($inputs); + throw new Exception("SELECT COUNT(*) FROM (SELECT COUNT(*) " . $query . " ) AS T2"); $totalCount = RedBean::getAll("SELECT COUNT(*) FROM (SELECT COUNT(*) " . $query . " ) AS T2")[0]['COUNT(*)']; - error_log(print_r("SELECT COUNT(*) FROM (SELECT COUNT(*) " . $query . " ) AS T2", true)); - error_log(print_r($totalCount, true)); - - $query = "SELECT ticket.id,ticket.title,ticket.ticket_number,ticket.content ,ticketevent.content " . $query; - - $this->setQueryOrder($order); - $query .= $order ." LIMIT 10 OFFSET " . (($page-1)*10); - - $ticketList = RedBean::getAll($query); + $ticketList = RedBean::getAll($queryWithOrder); Response::respondSuccess([ 'tickets' => $ticketList, @@ -125,61 +126,74 @@ class SearchController extends Controller { ]); } - //FILTER - private function setQueryFilters(&$filters){ - $this->setTagFilter($filters); - $this->setClosedFilter($filters); - $this->setAssignedFilter($filters); - $this->setSeenFilter($filters); - $this->setPriorityFilter($filters); - $this->setDateFilter($filters); - $this->setDepartmentFilter($filters); - $this->setAuthorFilter($filters); - $this->setStringFilter($filters); + public function getSQLQuery($inputs) { + $query = "FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id)"; + $filters = ""; + $this->setQueryFilters($inputs, $filters); + $query .= $filters . " GROUP BY ticket.id"; + return $query; + } + + public function getSQLQueryWithOrder($inputs) { + $query = $this->getSQLQuery($inputs); + $order = ""; + $query = "SELECT ticket.id,ticket.title,ticket.ticket_number,ticket.content ,ticketevent.content " . $query; + + $this->setQueryOrder($inputs, $order); + $inputs['page'] ? $page = $inputs['page'] : $page = 1 ; + $query .= $order ." LIMIT 10 OFFSET " . (($page-1)*10); + return $query; + } + + //FILTER + private function setQueryFilters($inputs, &$filters){ + if(array_key_exists('tags',$inputs)) $this->setTagFilter($inputs['tags'], $filters); + if(array_key_exists('closed',$inputs)) $this->setClosedFilter($inputs['closed'], $filters); + if(array_key_exists('assigned',$inputs)) $this->setAssignedFilter($inputs['assigned'], $filters); + if(array_key_exists('unreadStaff',$inputs)) $this->setSeenFilter($inputs['unreadStaff'], $filters); + if(array_key_exists('priority',$inputs)) $this->setPriorityFilter($inputs['priority'], $filters); + if(array_key_exists('dateRange',$inputs)) $this->setDateFilter($inputs['dateRange'], $filters); + if(array_key_exists('departments',$inputs)) $this->setDepartmentFilter($inputs['departments'], $filters); + if(array_key_exists('authors',$inputs)) $this->setAuthorFilter($inputs['authors'], $filters); + if(array_key_exists('query',$inputs)) $this->setStringFilter($inputs['query'], $filters); if($filters != "") $filters = " WHERE " . $filters; } - - private function setTagFilter(&$filters){ - $tagList = json_decode(Controller::request('tags')); + private function setTagFilter($tagList, &$filters){ if($tagList){ $filters != "" ? $filters .= " and " : null; - foreach($tagList as $key => $tag) { + foreach($tagList as $key => $tag) { $key == 0 ? $filters .= " ( " : null; ($key != 0 && $key != sizeof($tagList)) ? $filters .= " or " : null; - + $filters .= "tag_ticket.tag_id = " . $tag ; } $filters .= ")"; } } - private function setClosedFilter(&$filters){ - $closed = Controller::request('closed'); - + public function setClosedFilter($closed, &$filters){ if ($closed != null) { if ($filters != "") $filters .= " and "; $filters .= "ticket.closed = " . $closed ; - } + } } - private function setSeenFilter(&$filters){ - $unreadStaff = Controller::request('unreadStaff'); + private function setSeenFilter($unreadStaff, &$filters){ if ($unreadStaff != null) { if ($filters != "") $filters .= " and "; $filters .= "ticket.unread_staff = " . $unreadStaff; - } + } } - private function setPriorityFilter(&$filters){ - $prioritys = json_decode(Controller::request('priority')); + private function setPriorityFilter($prioritys, &$filters){ if($prioritys != null){ if ($filters != "") $filters .= " and "; foreach(array_unique($prioritys) as $key => $priority) { $key == 0 ? $filters .= " ( " : null; ($key != 0 && $key != sizeof($prioritys)) ? $filters .= " or " : null; - + if($priority == 0){ $filters .= "ticket.priority = " . "'low'"; }elseif($priority == 1){ @@ -193,62 +207,55 @@ class SearchController extends Controller { $prioritys != "" ? $filters .= ") " : null; } } - - private function setDateFilter(&$filters){ - $dateRange = json_decode(Controller::request('dateRange')); + + private function setDateFilter($dateRange, &$filters){ if ($dateRange != null) { if ($filters != "") $filters .= " and "; foreach($dateRange as $key => $date) { $key == 0 ? ($filters .= "(ticket.date >= " . $date ): ($filters .= " and ticket.date <= " . $date . ")"); } - } + } } - private function setDepartmentFilter(&$filters){ - - $departments = json_decode(Controller::request('departments')); - + private function setDepartmentFilter($departments, &$filters){ if($departments != null){ if ($filters != "") $filters .= " and "; - foreach($departments as $key => $department) { + foreach($departments as $key => $department) { $key == 0 ? $filters .= " ( " : null; ($key != 0 && $key != sizeof($departments)) ? $filters .= " or " : null; - + $filters .= "ticket.department_id = " . $department ; } $filters .= ")"; } } - private function setAuthorFilter(&$filters){ - $authors = json_decode(Controller::request('authors')); - + private function setAuthorFilter($authors, &$filters){ if($authors != null){ if ($filters != "") $filters .= " and "; - + foreach($authors as $key => $author){ $key == 0 ? $filters .= " ( " : null; ($key != 0 && $key != sizeof($authors)) ? $filters .= " or " : null; - - if($author->staff){ - $filters .= "ticket.author_staff_id = " . $author->id; + + if($author['staff']){ + $filters .= "ticket.author_staff_id = " . $author['id']; } else { - $filters .= "ticket.author_id = " . $author->id; + $filters .= "ticket.author_id = " . $author['id']; } } $filters .= ")"; - + } } - private function setAssignedFilter(&$filters){ - $assigned = Controller::request('assigned'); + private function setAssignedFilter($assigned, &$filters){ if($assigned != null){ if ($filters != "") $filters .= " and "; $key = ""; @@ -257,34 +264,30 @@ class SearchController extends Controller { } } - private function setStringFilter(&$filters){ - $string = Controller::request('query'); - if($string != null){ + private function setStringFilter($search, &$filters){ + if($search != null){ if ($filters != "") $filters .= " and "; - $filters .= " (ticket.title LIKE '%" . $string . "%' or ticket.content LIKE '%" . $string . "%' or ticket.ticket_number LIKE '%" . $string . "%' or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%" . $string ."%'))"; + $filters .= " (ticket.title LIKE '%" . $search . "%' or ticket.content LIKE '%" . $search . "%' or ticket.ticket_number LIKE '%" . $search . "%' or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%" . $search ."%'))"; }; } //ORDER - private function setQueryOrder(&$order){ + private function setQueryOrder($inputs, &$order){ $order = " ORDER BY "; - $this->setStringOrder($order); - $this->setEspecificOrder($order); + if(array_key_exists('query',$inputs)) $this->setStringOrder($inputs['query'], $order); + if(array_key_exists('orderBy',$inputs)) $this->setEspecificOrder($inputs['orderBy'], $order); $order .= "ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.priority desc, ticket.date desc "; } - private function setEspecificOrder(&$order){ - $orderBy = json_decode(Controller::request('orderBy')); + private function setEspecificOrder($orderBy, &$order){ if($orderBy != null){ - $orientation = ($orderBy->asc ? " asc" : " desc" ); - $order .= "ticket." . $orderBy->value . $orientation . ","; + $orientation = ($orderBy['asc'] ? " asc" : " desc" ); + $order .= "ticket." . $orderBy['value'] . $orientation . ","; }; } - private function setStringOrder(&$order){ - $string = Controller::request('query'); - if($string != null){ - $order .= "CASE WHEN (ticket.ticket_number LIKE '%" . $string ."%') THEN ticket.ticket_number END desc,CASE WHEN (ticket.title LIKE '%" . $string ."%') THEN ticket.title END desc, CASE WHEN ( ticket.content LIKE '%" . $string ."%') THEN ticket.content END desc, CASE WHEN (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%".$string."%') THEN ticketevent.content END desc," ; + private function setStringOrder($querysearch, &$order){ + if($querysearch != null){ + $order .= "CASE WHEN (ticket.ticket_number LIKE '%" . $querysearch ."%') THEN ticket.ticket_number END desc,CASE WHEN (ticket.title LIKE '%" . $querysearch ."%') THEN ticket.title END desc, CASE WHEN ( ticket.content LIKE '%" . $querysearch ."%') THEN ticket.content END desc, CASE WHEN (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%".$querysearch."%') THEN ticketevent.content END desc," ; } } } - diff --git a/server/libs/validations/validOrderBy.php b/server/libs/validations/validOrderBy.php index 4fed26c1..44466805 100644 --- a/server/libs/validations/validOrderBy.php +++ b/server/libs/validations/validOrderBy.php @@ -10,13 +10,13 @@ class ValidOrderBy extends AbstractRule { $values =["closed","owner_id","unread_staff","priority","date"]; $isTrue = false; $object = json_decode($orderBy); - - if($object->asc !== true && $object->asc !== false) return false; - + + if($object->asc !== 1 && $object->asc !== 0) return false; + foreach ($values as $value) { if($object->value == $value) $isTrue = true; - } + } return $isTrue; } } -} \ No newline at end of file +} diff --git a/server/tests/__mocks__/ControllerMock.php b/server/tests/__mocks__/ControllerMock.php index 7a4e8149..fa24452a 100755 --- a/server/tests/__mocks__/ControllerMock.php +++ b/server/tests/__mocks__/ControllerMock.php @@ -1,13 +1,19 @@ returns(false)); + Controller::useValueReturn(); $this->loginController->handler(); - $this->assertTrue(!!Session::getInstance()->createSession->hasBeenCalledWithArgs('MOCK_ID', false)); $this->assertTrue(Response::get('respondSuccess')->hasBeenCalledWithArgs(array( 'userId' => 'MOCK_ID', diff --git a/server/tests/libs/LinearCongruentialGeneratorTest.php b/server/tests/libs/LinearCongruentialGeneratorTest.php index 5d5f671f..b716612d 100644 --- a/server/tests/libs/LinearCongruentialGeneratorTest.php +++ b/server/tests/libs/LinearCongruentialGeneratorTest.php @@ -4,6 +4,7 @@ use PHPUnit\Framework\TestCase; class LinearCongruentialGeneratorTest extends TestCase { public function testAvoidCollisions() { + return; $TEST_TIMES = 10; $GENERATE_TIMES = 500000; $min = 100000; diff --git a/tests/staff/get-all.rb b/tests/staff/get-all.rb index dec7fdc5..5ba054cb 100644 --- a/tests/staff/get-all.rb +++ b/tests/staff/get-all.rb @@ -14,10 +14,10 @@ describe'/staff/get-all' do (result['data'][0]['email']).should.equal('staff@opensupports.com') (result['data'][0]['profilePic']).should.equal('') (result['data'][0]['level']).should.equal('3') - (result['data'][0]['departments'][0]['id']).should.equal('2') - (result['data'][0]['departments'][0]['name']).should.equal('useless private deapartment') - (result['data'][0]['departments'][1]['id']).should.equal('1') - (result['data'][0]['departments'][1]['name']).should.equal('Help and Support') + (result['data'][0]['departments'][0]['id']).should.equal('1') + (result['data'][0]['departments'][0]['name']).should.equal('Help and Support') + (result['data'][0]['departments'][1]['id']).should.equal('2') + (result['data'][0]['departments'][1]['name']).should.equal('useless private deapartment') (result['data'][0]['departments'][2]['id']).should.equal('3') (result['data'][0]['departments'][2]['name']).should.equal('Suggestions') (result['data'][0]['assignedTickets']).should.equal(10) diff --git a/tests/ticket/search.rb b/tests/ticket/search.rb new file mode 100644 index 00000000..c1c4d53f --- /dev/null +++ b/tests/ticket/search.rb @@ -0,0 +1,22 @@ +describe '/user/get' do + request('/user/logout') + + + #Scripts.createUser('user_get@os4.com', 'user_get','User Get') + + #Scripts.login('user_get@os4.com', 'user_get') + #result = request('/ticket/create', { + title: 'Should we pay?', + content: 'A Lannister always pays his debts.', + departmentId: 1, + language: 'en', + csrf_userid: $csrf_userid, + csrf_token: $csrf_token + }) + request('/user/logout') + #$database.query("INSERT INTO ticket(id,ticket_number) VALUES(58,123456,1,'low',1,'titulo','contentlargo','en',null,201911101213,1,'hola@os4.com','nameuatuhor',1,1,1,null);") + + + #@ticketNumber = result['data']['ticketNumber'] + request('/user/logout') +end From 5219b91388bb8ae8b31008523dddbb216d7fe05a Mon Sep 17 00:00:00 2001 From: Guillermo Date: Tue, 19 Nov 2019 19:55:47 -0300 Subject: [PATCH 03/19] add valid departments to staff search --- server/controllers/staff/get-all-tickets.php | 1 - server/controllers/ticket/search.php | 113 +++++++++++++----- .../libs/validations/validDepartmentsId.php | 2 +- 3 files changed, 83 insertions(+), 33 deletions(-) diff --git a/server/controllers/staff/get-all-tickets.php b/server/controllers/staff/get-all-tickets.php index 93a30975..f271acf2 100755 --- a/server/controllers/staff/get-all-tickets.php +++ b/server/controllers/staff/get-all-tickets.php @@ -50,7 +50,6 @@ class GetAllTicketsStaffController extends Controller { ]); return; } - Response::respondSuccess([ 'tickets' => $this->getTicketList()->toArray(true), 'pages' => $this->getTotalPages() diff --git a/server/controllers/ticket/search.php b/server/controllers/ticket/search.php index 0f9f9f1e..a53c7334 100644 --- a/server/controllers/ticket/search.php +++ b/server/controllers/ticket/search.php @@ -52,7 +52,7 @@ class SearchController extends Controller { public function validations() { return [ - 'permission' => 'any', + 'permission' => 'staff_1', 'requestData' => [ 'page' => [ 'validation' => DataValidator::oneOf(DataValidator::numeric()->positive(),DataValidator::nullType()), @@ -110,25 +110,38 @@ class SearchController extends Controller { 'assigned' => Controller::request('assigned'), 'query' => Controller::request('query'), 'orderBy' => json_decode(Controller::request('orderBy'),true), - 'page' => Controller::request('page') + 'page' => Controller::request('page'), + 'user' => Controller::getLoggedUser(), ]; + $query = $this->getSQLQuery($inputs); $queryWithOrder = $this->getSQLQueryWithOrder($inputs); - throw new Exception("SELECT COUNT(*) FROM (SELECT COUNT(*) " . $query . " ) AS T2"); $totalCount = RedBean::getAll("SELECT COUNT(*) FROM (SELECT COUNT(*) " . $query . " ) AS T2")[0]['COUNT(*)']; $ticketList = RedBean::getAll($queryWithOrder); - Response::respondSuccess([ - 'tickets' => $ticketList, - 'pages' => ceil($totalCount / 10), - 'page' => Controller::request('page') - ]); + $ticketTableExists = RedBean::exec("select table_name from information_schema.tables where table_name = 'ticket';"); + + if($ticketTableExists){ + Response::respondSuccess([ + 'tickets' => $ticketList, + 'pages' => ceil($totalCount / 10), + 'page' => $inputs['page'] ? $inputs['page'] : 1 + ]); + }else{ + Response::respondSuccess([]); + } } public function getSQLQuery($inputs) { - $query = "FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id)"; + $tagsTableExists = RedBean::exec("select table_name from information_schema.tables where table_name = 'tag_ticket';"); + $ticketEventTableExists = RedBean::exec("select table_name from information_schema.tables where table_name = 'ticketevent';"); + + $taglistQuery = ( $tagsTableExists ? " LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id" : ''); + $ticketeventlistQuery = ( $ticketEventTableExists ? " LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id" : ''); + + $query = "FROM (ticket" . $taglistQuery . $ticketeventlistQuery .")"; $filters = ""; $this->setQueryFilters($inputs, $filters); $query .= $filters . " GROUP BY ticket.id"; @@ -138,7 +151,7 @@ class SearchController extends Controller { public function getSQLQueryWithOrder($inputs) { $query = $this->getSQLQuery($inputs); $order = ""; - $query = "SELECT ticket.id,ticket.title,ticket.ticket_number,ticket.content ,ticketevent.content " . $query; + $query = "SELECT ticket.id,ticket.title,ticket.ticket_number, ticket.priority ,ticket.department_id, ticket.author_id , ticket.date " . $query; $this->setQueryOrder($inputs, $order); $inputs['page'] ? $page = $inputs['page'] : $page = 1 ; @@ -154,14 +167,16 @@ class SearchController extends Controller { if(array_key_exists('unreadStaff',$inputs)) $this->setSeenFilter($inputs['unreadStaff'], $filters); if(array_key_exists('priority',$inputs)) $this->setPriorityFilter($inputs['priority'], $filters); if(array_key_exists('dateRange',$inputs)) $this->setDateFilter($inputs['dateRange'], $filters); - if(array_key_exists('departments',$inputs)) $this->setDepartmentFilter($inputs['departments'], $filters); + if(array_key_exists('departments',$inputs)) $this->setDepartmentFilter($inputs['departments'],$inputs['user'], $filters); if(array_key_exists('authors',$inputs)) $this->setAuthorFilter($inputs['authors'], $filters); if(array_key_exists('query',$inputs)) $this->setStringFilter($inputs['query'], $filters); if($filters != "") $filters = " WHERE " . $filters; } private function setTagFilter($tagList, &$filters){ - if($tagList){ + $tagsTableExists = RedBean::exec("select table_name from information_schema.tables where table_name = 'tag_ticket';"); + + if($tagList && $tagsTableExists){ $filters != "" ? $filters .= " and " : null; foreach($tagList as $key => $tag) { @@ -188,11 +203,16 @@ class SearchController extends Controller { } private function setPriorityFilter($prioritys, &$filters){ if($prioritys != null){ + $first = TRUE; if ($filters != "") $filters .= " and "; - foreach(array_unique($prioritys) as $key => $priority) { + foreach(array_unique($prioritys) as $priority) { - $key == 0 ? $filters .= " ( " : null; - ($key != 0 && $key != sizeof($prioritys)) ? $filters .= " or " : null; + if($first){ + $filters .= " ( "; + $first = FALSE; + } else { + $filters .= " or "; + } if($priority == 0){ $filters .= "ticket.priority = " . "'low'"; @@ -202,10 +222,11 @@ class SearchController extends Controller { $filters .= "ticket.priority = " . "'high'"; } - $key == sizeof($prioritys) ? $filters .= " ) " : null ; + } $prioritys != "" ? $filters .= ") " : null; } + } private function setDateFilter($dateRange, &$filters){ @@ -218,30 +239,38 @@ class SearchController extends Controller { } } - private function setDepartmentFilter($departments, &$filters){ - if($departments != null){ - if ($filters != "") $filters .= " and "; + private function setDepartmentFilter($departments,$user, &$filters){ - foreach($departments as $key => $department) { + $validDepartments = $this->generateValidDepartmentList($departments, $user); + if ($filters != "") $filters .= " and "; + $first = TRUE; - $key == 0 ? $filters .= " ( " : null; - ($key != 0 && $key != sizeof($departments)) ? $filters .= " or " : null; - - $filters .= "ticket.department_id = " . $department ; + foreach($validDepartments as $department) { + if($first){ + $filters .= " ( "; + $first = FALSE; + } else { + $filters .= " or "; } - $filters .= ")"; + $filters .= "ticket.department_id = " . $department; } + $filters .= ")"; + } private function setAuthorFilter($authors, &$filters){ if($authors != null){ - + $first = TRUE; if ($filters != "") $filters .= " and "; - foreach($authors as $key => $author){ + foreach($authors as $author){ - $key == 0 ? $filters .= " ( " : null; - ($key != 0 && $key != sizeof($authors)) ? $filters .= " or " : null; + if($first){ + $filters .= " ( "; + $first = FALSE; + } else { + $filters .= " or "; + } if($author['staff']){ $filters .= "ticket.author_staff_id = " . $author['id']; @@ -265,12 +294,31 @@ class SearchController extends Controller { } private function setStringFilter($search, &$filters){ + $ticketEventTableExists = RedBean::exec("select table_name from information_schema.tables where table_name = 'ticketevent';"); + if($search != null){ if ($filters != "") $filters .= " and "; - $filters .= " (ticket.title LIKE '%" . $search . "%' or ticket.content LIKE '%" . $search . "%' or ticket.ticket_number LIKE '%" . $search . "%' or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%" . $search ."%'))"; + $ticketevent = ( $ticketEventTableExists ? " or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%" . $search ."%')" : ""); + $filters .= " (ticket.title LIKE '%" . $search . "%' or ticket.content LIKE '%" . $search . "%' or ticket.ticket_number LIKE '%" . $search . "%'". $ticketevent ." )"; }; } + private function generateValidDepartmentList($departments, $user){ + $result = []; + $managedDepartments = []; + if($departments == null) $departments = []; + foreach ($user->sharedDepartmentList->toArray() as $department) { + array_push($managedDepartments,$department['id']); + } + $result = array_intersect($departments,$managedDepartments); + + if(empty($result)) $result = $managedDepartments; + + $result = array_unique($result); + + return $result; + } + //ORDER private function setQueryOrder($inputs, &$order){ $order = " ORDER BY "; @@ -285,8 +333,11 @@ class SearchController extends Controller { }; } private function setStringOrder($querysearch, &$order){ + $ticketEventTableExists = RedBean::exec("select table_name from information_schema.tables where table_name = 'ticketevent';"); + if($querysearch != null){ - $order .= "CASE WHEN (ticket.ticket_number LIKE '%" . $querysearch ."%') THEN ticket.ticket_number END desc,CASE WHEN (ticket.title LIKE '%" . $querysearch ."%') THEN ticket.title END desc, CASE WHEN ( ticket.content LIKE '%" . $querysearch ."%') THEN ticket.content END desc, CASE WHEN (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%".$querysearch."%') THEN ticketevent.content END desc," ; + $ticketeventOrder = ( $ticketEventTableExists ? " CASE WHEN (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%".$querysearch."%') THEN ticketevent.content END desc," : ""); + $order .= "CASE WHEN (ticket.ticket_number LIKE '%" . $querysearch ."%') THEN ticket.ticket_number END desc,CASE WHEN (ticket.title LIKE '%" . $querysearch ."%') THEN ticket.title END desc, CASE WHEN ( ticket.content LIKE '%" . $querysearch ."%') THEN ticket.content END desc," . $ticketeventOrder ; } } diff --git a/server/libs/validations/validDepartmentsId.php b/server/libs/validations/validDepartmentsId.php index 44fa53f3..36c5b927 100644 --- a/server/libs/validations/validDepartmentsId.php +++ b/server/libs/validations/validDepartmentsId.php @@ -17,4 +17,4 @@ class ValidDepartmentsId extends AbstractRule { } return false; } -} \ No newline at end of file +} From 2678947f85e85a03c26587de29b03065b1cc8604 Mon Sep 17 00:00:00 2001 From: Guillermo Date: Tue, 17 Dec 2019 08:35:04 -0300 Subject: [PATCH 04/19] ticket search list frontend --- client/src/app-components/ticket-list.js | 2 +- .../src/app-components/ticket-query-list.js | 84 ++++++ client/src/app/Routes.js | 2 + .../tickets/admin-panel-search-tickets.js | 32 +++ client/src/core-components/menu.js | 2 +- client/src/core-components/menu.scss | 2 +- client/src/core-components/pagination.js | 2 +- client/src/core-components/table.js | 12 +- client/src/data/languages/en.js | 2 + server/controllers/staff/get-all-tickets.php | 1 + server/controllers/ticket/search.php | 14 +- .../tests/controllers/ticket/searchTest.php | 258 ++++++++++++++++++ tests/init.rb | 3 +- 13 files changed, 400 insertions(+), 16 deletions(-) create mode 100644 client/src/app-components/ticket-query-list.js create mode 100644 client/src/app/admin/panel/tickets/admin-panel-search-tickets.js create mode 100644 server/tests/controllers/ticket/searchTest.php diff --git a/client/src/app-components/ticket-list.js b/client/src/app-components/ticket-list.js index d23ecf0f..6f85dc43 100644 --- a/client/src/app-components/ticket-list.js +++ b/client/src/app-components/ticket-list.js @@ -274,4 +274,4 @@ export default connect((store) => { return { tags: store.config['tags'] }; -})(TicketList); \ No newline at end of file +})(TicketList); diff --git a/client/src/app-components/ticket-query-list.js b/client/src/app-components/ticket-query-list.js new file mode 100644 index 00000000..a5c7edbc --- /dev/null +++ b/client/src/app-components/ticket-query-list.js @@ -0,0 +1,84 @@ +import React from 'react'; +import _ from 'lodash'; + +import API from 'lib-app/api-call'; +import i18n from 'lib-app/i18n'; +import {connect} from 'react-redux'; + +import TicketList from 'app-components/ticket-list'; +import Message from 'core-components/message'; + +class TicketQueryList extends React.Component { + + state = { + tickets: [], + page: 1, + pages: 0, + error: null, + loading: true + }; + + componentDidMount() { + this.getTickets(); + } + + render() { + return ( +
+ {(this.state.error) ? {i18n('ERROR_RETRIEVING_TICKETS')} : } +
+ ); + } + + getTickets() { + this.setState({ + loading:true + }) + API.call({ + path: '/ticket/search', + data: { + page : this.state.page, + ...this.props.filters + } + }).then((result) => { + this.setState({ + tickets: result.data.tickets, + page: result.data.page, + pages: result.data.pages, + error: null, + loading: false + }) + }).catch((result) => this.setState({ + loading: false, + error: result.message + })); + + } + + onPageChange(event) { + this.setState({page: event.target.value}, () => this.getTickets()); + } + + getTicketListProps () { + const {page,pages,loading,tickets} = this.state; + return { + userId: this.props.userId, + ticketPath: '/admin/panel/tickets/view-ticket/', + tickets, + page, + pages, + loading, + type: 'secondary', + showDepartmentDropdown: false, + closedTicketsShown: false, + onPageChange:this.onPageChange.bind(this) + }; + } + +} + +export default connect((store) => { + return { + userId: store.session.userId + }; +})(TicketQueryList); diff --git a/client/src/app/Routes.js b/client/src/app/Routes.js index 0419c0db..b9d43065 100644 --- a/client/src/app/Routes.js +++ b/client/src/app/Routes.js @@ -33,6 +33,7 @@ import AdminPanelMyAccount from 'app/admin/panel/dashboard/admin-panel-my-accoun import AdminPanelMyTickets from 'app/admin/panel/tickets/admin-panel-my-tickets'; import AdminPanelNewTickets from 'app/admin/panel/tickets/admin-panel-new-tickets'; import AdminPanelAllTickets from 'app/admin/panel/tickets/admin-panel-all-tickets'; +import AdminPanelSearchTickets from 'app/admin/panel/tickets/admin-panel-search-tickets'; import AdminPanelViewTicket from 'app/admin/panel/tickets/admin-panel-view-ticket'; import AdminPanelCustomResponses from 'app/admin/panel/tickets/admin-panel-custom-responses'; @@ -113,6 +114,7 @@ export default ( + diff --git a/client/src/app/admin/panel/tickets/admin-panel-search-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-search-tickets.js new file mode 100644 index 00000000..b9f4842d --- /dev/null +++ b/client/src/app/admin/panel/tickets/admin-panel-search-tickets.js @@ -0,0 +1,32 @@ +import React from 'react'; +import {connect} from 'react-redux'; + +import i18n from 'lib-app/i18n'; + +import TicketQueryList from 'app-components/ticket-query-list'; + +import Header from 'core-components/header'; +import Message from 'core-components/message'; + +class AdminPanelSearchTickets extends React.Component { + + render() { + return ( +
+
+ {(this.props.error) ? {i18n('ERROR_RETRIEVING_TICKETS')} : } +
+ ); + } + + getFilters() { + return { + }; + } +} + +export default connect((store) => { + return { + error: store.adminData.allTicketsError + }; +})(AdminPanelSearchTickets); diff --git a/client/src/core-components/menu.js b/client/src/core-components/menu.js index 25cd805d..40ef6de2 100644 --- a/client/src/core-components/menu.js +++ b/client/src/core-components/menu.js @@ -140,4 +140,4 @@ class Menu extends React.Component { } } -export default Menu; \ No newline at end of file +export default Menu; diff --git a/client/src/core-components/menu.scss b/client/src/core-components/menu.scss index 64eab16c..d8b06c20 100644 --- a/client/src/core-components/menu.scss +++ b/client/src/core-components/menu.scss @@ -201,4 +201,4 @@ $transition: background-color 0.3s ease, color 0.3s ease; color: white; } } -} \ No newline at end of file +} diff --git a/client/src/core-components/pagination.js b/client/src/core-components/pagination.js index 4b4ad162..8ce28a8d 100644 --- a/client/src/core-components/pagination.js +++ b/client/src/core-components/pagination.js @@ -98,4 +98,4 @@ class Pagination extends React.Component { } } -export default Pagination; \ No newline at end of file +export default Pagination; diff --git a/client/src/core-components/table.js b/client/src/core-components/table.js index fe882f72..07c9f29f 100644 --- a/client/src/core-components/table.js +++ b/client/src/core-components/table.js @@ -55,7 +55,7 @@ class Table extends React.Component { 'table__header-column': true, [header.className]: (header.className) }; - + return ( {header.value} @@ -97,7 +97,7 @@ class Table extends React.Component { }; return ( - + {row[key]} ); } @@ -139,15 +139,15 @@ class Table extends React.Component { this.props.onPageChange({target: {value: index}}); } } - + getRowClass(row) { let classes = { 'table__row': true, 'table__row-highlighted': row.highlighted }; - + classes[row.className] = (row.className); - + return classNames(classes); } @@ -167,4 +167,4 @@ class Table extends React.Component { } } -export default Table; \ No newline at end of file +export default Table; diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index 6373f738..b29c60d1 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -93,6 +93,7 @@ export default { 'CHANGE_EMAIL': 'Change email', 'CHANGE_PASSWORD': 'Change password', 'NAME': 'Name', + 'SEARCH': 'Search', 'SIGNUP_DATE': 'Sign up date', 'SEARCH_USERS': 'Search users...', 'SEARCH_EMAIL': 'Search email...', @@ -293,6 +294,7 @@ export default { 'MY_TICKETS_DESCRIPTION': 'Here you can view the tickets you are responsible for.', 'NEW_TICKETS_DESCRIPTION': 'Here you can view all the new tickets that are not assigned by anyone.', 'ALL_TICKETS_DESCRIPTION': 'Here you can view the tickets of the departments you are assigned.', + 'SEARCH_TICKETS_DESCRIPTION': 'Here you can search tickets by specifics filters.', 'TICKET_VIEW_DESCRIPTION': 'This ticket has been sent by a customer. Here you can respond or assign the ticket', 'BAN_USERS_DESCRIPTION': 'Here you can see a list of banned emails, you can un-ban them or add more emails to the list.', 'LIST_USERS_DESCRIPTION': 'This is the list of users that are registered in this platform. You can search for someone in particular, delete it or ban it.', diff --git a/server/controllers/staff/get-all-tickets.php b/server/controllers/staff/get-all-tickets.php index f271acf2..a1530e8f 100755 --- a/server/controllers/staff/get-all-tickets.php +++ b/server/controllers/staff/get-all-tickets.php @@ -50,6 +50,7 @@ class GetAllTicketsStaffController extends Controller { ]); return; } + Response::respondSuccess([ 'tickets' => $this->getTicketList()->toArray(true), 'pages' => $this->getTotalPages() diff --git a/server/controllers/ticket/search.php b/server/controllers/ticket/search.php index a53c7334..62b49ada 100644 --- a/server/controllers/ticket/search.php +++ b/server/controllers/ticket/search.php @@ -116,17 +116,21 @@ class SearchController extends Controller { $query = $this->getSQLQuery($inputs); $queryWithOrder = $this->getSQLQueryWithOrder($inputs); - $totalCount = RedBean::getAll("SELECT COUNT(*) FROM (SELECT COUNT(*) " . $query . " ) AS T2")[0]['COUNT(*)']; - $ticketList = RedBean::getAll($queryWithOrder); + $ticketIdList = RedBean::getAll($queryWithOrder); + $ticketList = []; + + foreach ($ticketIdList as $item) { + $ticket = Ticket::getDataStore($item['id']); + array_push($ticketList, $ticket->toArray()); + } $ticketTableExists = RedBean::exec("select table_name from information_schema.tables where table_name = 'ticket';"); - if($ticketTableExists){ Response::respondSuccess([ 'tickets' => $ticketList, 'pages' => ceil($totalCount / 10), - 'page' => $inputs['page'] ? $inputs['page'] : 1 + 'page' => $inputs['page'] ? ($inputs['page']*1) : 1 ]); }else{ Response::respondSuccess([]); @@ -151,7 +155,7 @@ class SearchController extends Controller { public function getSQLQueryWithOrder($inputs) { $query = $this->getSQLQuery($inputs); $order = ""; - $query = "SELECT ticket.id,ticket.title,ticket.ticket_number, ticket.priority ,ticket.department_id, ticket.author_id , ticket.date " . $query; + $query = "SELECT" . " ticket.id " . $query; $this->setQueryOrder($inputs, $order); $inputs['page'] ? $page = $inputs['page'] : $page = 1 ; diff --git a/server/tests/controllers/ticket/searchTest.php b/server/tests/controllers/ticket/searchTest.php new file mode 100644 index 00000000..b7f72f46 --- /dev/null +++ b/server/tests/controllers/ticket/searchTest.php @@ -0,0 +1,258 @@ + \Mock::stub()->returns(1) + ]); + Controller::$requestReturnMock = null; + $_SERVER['REMOTE_ADDR'] = 'MOCK_REMOTE'; + $this->searchController = new SearchController(); + } + + public function testTagsFilter() { + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'tags' => [] + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) GROUP BY ticket.id' + ); + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'tags' => [0] + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ( tag_ticket.tag_id = 0) GROUP BY ticket.id' + ); + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'tags' => [0,1,2] + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ( tag_ticket.tag_id = 0 or tag_ticket.tag_id = 1 or tag_ticket.tag_id = 2) GROUP BY ticket.id' + ); + } + + public function testClosedFilter() { + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'closed'=> null + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) GROUP BY ticket.id' + ); + + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'closed'=> 1 + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ticket.closed = 1 GROUP BY ticket.id' + ); + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'closed'=> '0' + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ticket.closed = 0 GROUP BY ticket.id' + ); + } + public function testAssignedFilter(){ + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'assigned'=> null + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) GROUP BY ticket.id' + ); + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'assigned'=> '0' + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ticket.owner_id IS NULL GROUP BY ticket.id' + ); + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'assigned'=> 1 + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ticket.owner_id IS NOT NULL GROUP BY ticket.id' + ); + } + public function testUnreadStaffFilter() { + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'unreadStaff' => null + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) GROUP BY ticket.id' + ); + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'unreadStaff' => '0' + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ticket.unread_staff = 0 GROUP BY ticket.id' + ); + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'unreadStaff' => 1 + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ticket.unread_staff = 1 GROUP BY ticket.id' + ); + } + + public function testPriorityFilter() { + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'tags' => [] + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) GROUP BY ticket.id' + ); + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'tags' => [1] + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ( tag_ticket.tag_id = 1) GROUP BY ticket.id' + ); + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'tags' => [2,3] + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ( tag_ticket.tag_id = 2 or tag_ticket.tag_id = 3) GROUP BY ticket.id' + ); + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'tags' => [1,2,3] + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ( tag_ticket.tag_id = 1 or tag_ticket.tag_id = 2 or tag_ticket.tag_id = 3) GROUP BY ticket.id' + ); + } + + public function testdateRangeFilter() { + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'dateRange' => null + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) GROUP BY ticket.id' + ); + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'dateRange' => [1,2] + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE (ticket.date >= 1 and ticket.date <= 2) GROUP BY ticket.id' + ); + } + /* + public function testDepartmentsFilter() { + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'departments' => null + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) GROUP BY ticket.id' + ); + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'departments' => [1] + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ( ticket.department_id = 1) GROUP BY ticket.id' + ); + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'departments' => [1,2,3] + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ( ticket.department_id = 1 or ticket.department_id = 2 or ticket.department_id = 3) GROUP BY ticket.id' + ); + } + */ + public function testAuthorsFilter() { + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'authors' => null + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) GROUP BY ticket.id' + ); + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'authors' => [ + [ + 'id' => 1, + 'staff' => 1 + ], + [ + 'id' => 2, + 'staff' => 0 + ] + ] + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ( ticket.author_staff_id = 1 or ticket.author_id = 2) GROUP BY ticket.id' + ); + } + + public function testQueryFilter() { + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'query' => null + ]), + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) GROUP BY ticket.id' + ); + + $this->assertEquals( + $this->searchController->getSQLQuery([ + 'query' => 'hello world' + ]), + "FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE (ticket.title LIKE '%hello world%' or ticket.content LIKE '%hello world%' or ticket.ticket_number LIKE '%hello world%' or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%hello world%') ) GROUP BY ticket.id" + ); + } + public function testQueryWithOrder() { + $this->assertEquals( + $this->searchController->getSQLQueryWithOrder([ + 'page' => 1 + ]), + "SELECT ticket.id,ticket.title,ticket.ticket_number, ticket.priority ,ticket.department_id, ticket.author_id , ticket.date FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) GROUP BY ticket.id ORDER BY ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.priority desc, ticket.date desc LIMIT 10 OFFSET 0" + ); + + $this->assertEquals( + $this->searchController->getSQLQueryWithOrder([ + 'page' => 1, + 'query' => 'stark' + ]), + "SELECT ticket.id,ticket.title,ticket.ticket_number, ticket.priority ,ticket.department_id, ticket.author_id , ticket.date FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE (ticket.title LIKE '%stark%' or ticket.content LIKE '%stark%' or ticket.ticket_number LIKE '%stark%' or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%stark%') ) GROUP BY ticket.id ORDER BY CASE WHEN (ticket.ticket_number LIKE '%stark%') THEN ticket.ticket_number END desc,CASE WHEN (ticket.title LIKE '%stark%') THEN ticket.title END desc, CASE WHEN ( ticket.content LIKE '%stark%') THEN ticket.content END desc, CASE WHEN (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%stark%') THEN ticketevent.content END desc,ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.priority desc, ticket.date desc LIMIT 10 OFFSET 0" + ); + + $this->assertEquals( + $this->searchController->getSQLQueryWithOrder([ + 'page' => 1, + 'orderBy' => ['value' => 'closed', 'asc' => 1] + ]), + "SELECT ticket.id,ticket.title,ticket.ticket_number, ticket.priority ,ticket.department_id, ticket.author_id , ticket.date FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) GROUP BY ticket.id ORDER BY ticket.closed asc,ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.priority desc, ticket.date desc LIMIT 10 OFFSET 0" + ); + } +} diff --git a/tests/init.rb b/tests/init.rb index 5f3ef8a0..73651ad3 100644 --- a/tests/init.rb +++ b/tests/init.rb @@ -22,10 +22,11 @@ require './user/send-recover-password.rb' require './user/recover-password.rb' require './user/edit-password.rb' require './user/edit-email.rb' +#require './ticket/search.rb' require './user/get.rb' require './user/enable-disable.rb' -require './ticket/create.rb' require './ticket/seen.rb' +require './ticket/create.rb' require './ticket/comment.rb' require './ticket/get.rb' require './ticket/custom-response.rb' From bac138757eeca1dd566ffeb4df16ab9e73dbe3ff Mon Sep 17 00:00:00 2001 From: Guillermo Date: Tue, 17 Dec 2019 09:04:49 -0300 Subject: [PATCH 05/19] fix search php test --- server/tests/controllers/ticket/searchTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/tests/controllers/ticket/searchTest.php b/server/tests/controllers/ticket/searchTest.php index b7f72f46..ad08fb5f 100644 --- a/server/tests/controllers/ticket/searchTest.php +++ b/server/tests/controllers/ticket/searchTest.php @@ -236,7 +236,7 @@ class SearchControllerTest extends TestCase { $this->searchController->getSQLQueryWithOrder([ 'page' => 1 ]), - "SELECT ticket.id,ticket.title,ticket.ticket_number, ticket.priority ,ticket.department_id, ticket.author_id , ticket.date FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) GROUP BY ticket.id ORDER BY ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.priority desc, ticket.date desc LIMIT 10 OFFSET 0" + "SELECT ticket.id FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) GROUP BY ticket.id ORDER BY ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.priority desc, ticket.date desc LIMIT 10 OFFSET 0" ); $this->assertEquals( @@ -244,7 +244,7 @@ class SearchControllerTest extends TestCase { 'page' => 1, 'query' => 'stark' ]), - "SELECT ticket.id,ticket.title,ticket.ticket_number, ticket.priority ,ticket.department_id, ticket.author_id , ticket.date FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE (ticket.title LIKE '%stark%' or ticket.content LIKE '%stark%' or ticket.ticket_number LIKE '%stark%' or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%stark%') ) GROUP BY ticket.id ORDER BY CASE WHEN (ticket.ticket_number LIKE '%stark%') THEN ticket.ticket_number END desc,CASE WHEN (ticket.title LIKE '%stark%') THEN ticket.title END desc, CASE WHEN ( ticket.content LIKE '%stark%') THEN ticket.content END desc, CASE WHEN (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%stark%') THEN ticketevent.content END desc,ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.priority desc, ticket.date desc LIMIT 10 OFFSET 0" + "SELECT ticket.id FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE (ticket.title LIKE '%stark%' or ticket.content LIKE '%stark%' or ticket.ticket_number LIKE '%stark%' or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%stark%') ) GROUP BY ticket.id ORDER BY CASE WHEN (ticket.ticket_number LIKE '%stark%') THEN ticket.ticket_number END desc,CASE WHEN (ticket.title LIKE '%stark%') THEN ticket.title END desc, CASE WHEN ( ticket.content LIKE '%stark%') THEN ticket.content END desc, CASE WHEN (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%stark%') THEN ticketevent.content END desc,ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.priority desc, ticket.date desc LIMIT 10 OFFSET 0" ); $this->assertEquals( @@ -252,7 +252,7 @@ class SearchControllerTest extends TestCase { 'page' => 1, 'orderBy' => ['value' => 'closed', 'asc' => 1] ]), - "SELECT ticket.id,ticket.title,ticket.ticket_number, ticket.priority ,ticket.department_id, ticket.author_id , ticket.date FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) GROUP BY ticket.id ORDER BY ticket.closed asc,ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.priority desc, ticket.date desc LIMIT 10 OFFSET 0" + "SELECT ticket.id FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) GROUP BY ticket.id ORDER BY ticket.closed asc,ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.priority desc, ticket.date desc LIMIT 10 OFFSET 0" ); } } From 58be6127fba8bf8d46be9706e34accbee2beb0b3 Mon Sep 17 00:00:00 2001 From: Guillermo Giuliana Date: Tue, 17 Dec 2019 09:15:52 -0300 Subject: [PATCH 06/19] Delete search.rb --- tests/ticket/search.rb | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 tests/ticket/search.rb diff --git a/tests/ticket/search.rb b/tests/ticket/search.rb deleted file mode 100644 index c1c4d53f..00000000 --- a/tests/ticket/search.rb +++ /dev/null @@ -1,22 +0,0 @@ -describe '/user/get' do - request('/user/logout') - - - #Scripts.createUser('user_get@os4.com', 'user_get','User Get') - - #Scripts.login('user_get@os4.com', 'user_get') - #result = request('/ticket/create', { - title: 'Should we pay?', - content: 'A Lannister always pays his debts.', - departmentId: 1, - language: 'en', - csrf_userid: $csrf_userid, - csrf_token: $csrf_token - }) - request('/user/logout') - #$database.query("INSERT INTO ticket(id,ticket_number) VALUES(58,123456,1,'low',1,'titulo','contentlargo','en',null,201911101213,1,'hola@os4.com','nameuatuhor',1,1,1,null);") - - - #@ticketNumber = result['data']['ticketNumber'] - request('/user/logout') -end From 2099af5f3a2eff4ef1b6cb169f917232206d88cc Mon Sep 17 00:00:00 2001 From: Guillermo Giuliana Date: Tue, 17 Dec 2019 10:15:19 -0300 Subject: [PATCH 07/19] Update LinearCongruentialGeneratorTest.php --- server/tests/libs/LinearCongruentialGeneratorTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/server/tests/libs/LinearCongruentialGeneratorTest.php b/server/tests/libs/LinearCongruentialGeneratorTest.php index b716612d..5d5f671f 100644 --- a/server/tests/libs/LinearCongruentialGeneratorTest.php +++ b/server/tests/libs/LinearCongruentialGeneratorTest.php @@ -4,7 +4,6 @@ use PHPUnit\Framework\TestCase; class LinearCongruentialGeneratorTest extends TestCase { public function testAvoidCollisions() { - return; $TEST_TIMES = 10; $GENERATE_TIMES = 500000; $min = 100000; From 870f5fea46766cb3bbf50fe63ae29d607bc8f08e Mon Sep 17 00:00:00 2001 From: Guillermo Date: Tue, 17 Dec 2019 11:05:22 -0300 Subject: [PATCH 08/19] puts get all ruby test --- tests/staff/get-all.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/staff/get-all.rb b/tests/staff/get-all.rb index 5ba054cb..23e089ae 100644 --- a/tests/staff/get-all.rb +++ b/tests/staff/get-all.rb @@ -8,6 +8,8 @@ describe'/staff/get-all' do csrf_token: $csrf_token }) + puts result['data'] + (result['status']).should.equal('success') (result['data'][0]['name']).should.equal('Emilia Clarke') From 61ce46d5c7eecbb219b7808b446cef77203f769b Mon Sep 17 00:00:00 2001 From: Guillermo Date: Tue, 17 Dec 2019 15:25:45 -0300 Subject: [PATCH 09/19] change name Validation priorities --- server/controllers/ticket/search.php | 10 +++++----- server/libs/validations/validPriorities.php | 19 +++++++++++++++++++ tests/init.rb | 3 +-- tests/system/get-settings.rb | 2 +- 4 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 server/libs/validations/validPriorities.php diff --git a/server/controllers/ticket/search.php b/server/controllers/ticket/search.php index 62b49ada..a3ea08fe 100644 --- a/server/controllers/ticket/search.php +++ b/server/controllers/ticket/search.php @@ -71,7 +71,7 @@ class SearchController extends Controller { 'error' => ERRORS::INVALID_UNREAD_STAFF_FILTER ], 'priority' => [ - 'validation' => DataValidator::oneOf(DataValidator::validPrioritys(),DataValidator::nullType()), + 'validation' => DataValidator::oneOf(DataValidator::validPriorities(),DataValidator::nullType()), 'error' => ERRORS::INVALID_PRIORITY_FILTER ], 'dateRange' => [ @@ -205,11 +205,11 @@ class SearchController extends Controller { $filters .= "ticket.unread_staff = " . $unreadStaff; } } - private function setPriorityFilter($prioritys, &$filters){ - if($prioritys != null){ + private function setPriorityFilter($priorities, &$filters){ + if($priorities != null){ $first = TRUE; if ($filters != "") $filters .= " and "; - foreach(array_unique($prioritys) as $priority) { + foreach(array_unique($priorities) as $priority) { if($first){ $filters .= " ( "; @@ -228,7 +228,7 @@ class SearchController extends Controller { } - $prioritys != "" ? $filters .= ") " : null; + $priorities != "" ? $filters .= ") " : null; } } diff --git a/server/libs/validations/validPriorities.php b/server/libs/validations/validPriorities.php new file mode 100644 index 00000000..7313deec --- /dev/null +++ b/server/libs/validations/validPriorities.php @@ -0,0 +1,19 @@ + Date: Tue, 17 Dec 2019 17:02:46 -0300 Subject: [PATCH 10/19] order departments get all ruby test --- tests/staff/get-all.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/staff/get-all.rb b/tests/staff/get-all.rb index 23e089ae..ed3753ad 100644 --- a/tests/staff/get-all.rb +++ b/tests/staff/get-all.rb @@ -8,10 +8,13 @@ describe'/staff/get-all' do csrf_token: $csrf_token }) - puts result['data'] - (result['status']).should.equal('success') + result['data'][0]['departments'].sort_by do |department| + department['id'].to_i + end + puts result['data'] + (result['data'][0]['name']).should.equal('Emilia Clarke') (result['data'][0]['email']).should.equal('staff@opensupports.com') (result['data'][0]['profilePic']).should.equal('') From c8634d457cd7bbc5bc9f26a4d30d90f08c18cbe1 Mon Sep 17 00:00:00 2001 From: Guillermo Date: Tue, 17 Dec 2019 17:28:02 -0300 Subject: [PATCH 11/19] order departments get all ruby test2 --- tests/staff/get-all.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/staff/get-all.rb b/tests/staff/get-all.rb index ed3753ad..432fa3cd 100644 --- a/tests/staff/get-all.rb +++ b/tests/staff/get-all.rb @@ -10,7 +10,7 @@ describe'/staff/get-all' do (result['status']).should.equal('success') - result['data'][0]['departments'].sort_by do |department| + result['data'][0]['departments'] = result['data'][0]['departments'].sort_by do |department| department['id'].to_i end puts result['data'] From 0bd099d05ac8f296d24df556e4fcd1ee7ba10001 Mon Sep 17 00:00:00 2001 From: Guillermo Date: Thu, 19 Dec 2019 17:06:12 -0300 Subject: [PATCH 12/19] add support for custom ticket lists --- .../src/app-components/ticket-query-list.js | 8 ++++++- .../src/app/admin/panel/admin-panel-menu.js | 21 +++++++++++++++++-- .../tickets/admin-panel-search-tickets.js | 4 +++- client/src/index.html | 1 - tests/staff/get-all.rb | 1 - 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/client/src/app-components/ticket-query-list.js b/client/src/app-components/ticket-query-list.js index a5c7edbc..f28dbc3b 100644 --- a/client/src/app-components/ticket-query-list.js +++ b/client/src/app-components/ticket-query-list.js @@ -22,6 +22,12 @@ class TicketQueryList extends React.Component { this.getTickets(); } + componentDidUpdate(prevProps) { + if (this.props.customList.title !== prevProps.customList.title) { + this.getTickets(); + } + } + render() { return (
@@ -38,7 +44,7 @@ class TicketQueryList extends React.Component { path: '/ticket/search', data: { page : this.state.page, - ...this.props.filters + ...this.props.customList.filters } }).then((result) => { this.setState({ diff --git a/client/src/app/admin/panel/admin-panel-menu.js b/client/src/app/admin/panel/admin-panel-menu.js index da34ccb7..20734df3 100644 --- a/client/src/app/admin/panel/admin-panel-menu.js +++ b/client/src/app/admin/panel/admin-panel-menu.js @@ -76,7 +76,7 @@ class AdminPanelMenu extends React.Component { getGroupItemIndex() { const group = this.getRoutes()[this.getGroupIndex()]; - const pathname = this.props.location.pathname; + const pathname = this.props.location.pathname + this.props.location.search; return _.findIndex(group.items, {path: pathname}); } @@ -90,7 +90,23 @@ class AdminPanelMenu extends React.Component { return (groupIndex === -1) ? 0 : groupIndex; } + getCustomlists() { + if(window.customTicketList){ + return window.customTicketList.map((item, index) => { + return { + name: item.title, + path: '/admin/panel/tickets/search-tickets?custom=' + index, + level: 1 + } + }) + } else { + return []; + } + } + getRoutes() { + const customLists = this.getCustomlists(); + return this.getItemsByFilteredByLevel([ { groupName: i18n('DASHBOARD'), @@ -135,7 +151,8 @@ class AdminPanelMenu extends React.Component { name: i18n('CUSTOM_RESPONSES'), path: '/admin/panel/tickets/custom-responses', level: 2 - } + }, + ...customLists ]) }, { diff --git a/client/src/app/admin/panel/tickets/admin-panel-search-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-search-tickets.js index b9f4842d..2dd4f530 100644 --- a/client/src/app/admin/panel/tickets/admin-panel-search-tickets.js +++ b/client/src/app/admin/panel/tickets/admin-panel-search-tickets.js @@ -14,13 +14,15 @@ class AdminPanelSearchTickets extends React.Component { return (
- {(this.props.error) ? {i18n('ERROR_RETRIEVING_TICKETS')} : } + {(this.props.error) ? {i18n('ERROR_RETRIEVING_TICKETS')} : }
); } getFilters() { + let customList = window.customTicketList[this.props.location.query.custom*1] ? window.customTicketList[this.props.location.query.custom*1] : null return { + ...customList }; } } diff --git a/client/src/index.html b/client/src/index.html index 90c8c2e2..a00af5b1 100755 --- a/client/src/index.html +++ b/client/src/index.html @@ -12,7 +12,6 @@
- diff --git a/tests/staff/get-all.rb b/tests/staff/get-all.rb index 432fa3cd..f8571c71 100644 --- a/tests/staff/get-all.rb +++ b/tests/staff/get-all.rb @@ -13,7 +13,6 @@ describe'/staff/get-all' do result['data'][0]['departments'] = result['data'][0]['departments'].sort_by do |department| department['id'].to_i end - puts result['data'] (result['data'][0]['name']).should.equal('Emilia Clarke') (result['data'][0]['email']).should.equal('staff@opensupports.com') From f9e8a0abec43119dd8e28a9973142af4848a1079 Mon Sep 17 00:00:00 2001 From: Guillermo Date: Thu, 26 Dec 2019 17:25:00 -0300 Subject: [PATCH 13/19] add department test and escape query --- server/controllers/ticket/search.php | 24 ++++----- server/libs/validations/validPrioritys.php | 19 ------- .../tests/controllers/ticket/searchTest.php | 50 ++++++++++++++++--- 3 files changed, 54 insertions(+), 39 deletions(-) delete mode 100644 server/libs/validations/validPrioritys.php diff --git a/server/controllers/ticket/search.php b/server/controllers/ticket/search.php index a3ea08fe..3eb05304 100644 --- a/server/controllers/ticket/search.php +++ b/server/controllers/ticket/search.php @@ -111,21 +111,22 @@ class SearchController extends Controller { 'query' => Controller::request('query'), 'orderBy' => json_decode(Controller::request('orderBy'),true), 'page' => Controller::request('page'), - 'user' => Controller::getLoggedUser(), + 'allowedDepartments' => Controller::getLoggedUser()->sharedDepartmentList->toArray(), ]; + $query = $this->getSQLQuery($inputs); $queryWithOrder = $this->getSQLQueryWithOrder($inputs); - $totalCount = RedBean::getAll("SELECT COUNT(*) FROM (SELECT COUNT(*) " . $query . " ) AS T2")[0]['COUNT(*)']; - $ticketIdList = RedBean::getAll($queryWithOrder); + $totalCount = RedBean::getAll("SELECT COUNT(*) FROM (SELECT COUNT(*) " . $query . " ) AS T2", [':query' => $inputs['query']])[0]['COUNT(*)']; + $ticketIdList = RedBean::getAll($queryWithOrder, [':query' => "%" . $inputs['query'] . "%"]); $ticketList = []; foreach ($ticketIdList as $item) { $ticket = Ticket::getDataStore($item['id']); array_push($ticketList, $ticket->toArray()); } - $ticketTableExists = RedBean::exec("select table_name from information_schema.tables where table_name = 'ticket';"); + if($ticketTableExists){ Response::respondSuccess([ 'tickets' => $ticketList, @@ -171,7 +172,7 @@ class SearchController extends Controller { if(array_key_exists('unreadStaff',$inputs)) $this->setSeenFilter($inputs['unreadStaff'], $filters); if(array_key_exists('priority',$inputs)) $this->setPriorityFilter($inputs['priority'], $filters); if(array_key_exists('dateRange',$inputs)) $this->setDateFilter($inputs['dateRange'], $filters); - if(array_key_exists('departments',$inputs)) $this->setDepartmentFilter($inputs['departments'],$inputs['user'], $filters); + if(array_key_exists('departments',$inputs)) $this->setDepartmentFilter($inputs['departments'],$inputs['allowedDepartments'], $filters); if(array_key_exists('authors',$inputs)) $this->setAuthorFilter($inputs['authors'], $filters); if(array_key_exists('query',$inputs)) $this->setStringFilter($inputs['query'], $filters); if($filters != "") $filters = " WHERE " . $filters; @@ -243,9 +244,8 @@ class SearchController extends Controller { } } - private function setDepartmentFilter($departments,$user, &$filters){ - - $validDepartments = $this->generateValidDepartmentList($departments, $user); + private function setDepartmentFilter($departments,$allowedDepartments, &$filters){ + $validDepartments = $this->generateValidDepartmentList($departments, $allowedDepartments); if ($filters != "") $filters .= " and "; $first = TRUE; @@ -302,16 +302,16 @@ class SearchController extends Controller { if($search != null){ if ($filters != "") $filters .= " and "; - $ticketevent = ( $ticketEventTableExists ? " or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%" . $search ."%')" : ""); - $filters .= " (ticket.title LIKE '%" . $search . "%' or ticket.content LIKE '%" . $search . "%' or ticket.ticket_number LIKE '%" . $search . "%'". $ticketevent ." )"; + $ticketevent = ( $ticketEventTableExists ? " or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE :query)" : ""); + $filters .= " (ticket.title LIKE :query or ticket.content LIKE :query or ticket.ticket_number LIKE :query". $ticketevent ." )"; }; } - private function generateValidDepartmentList($departments, $user){ + private function generateValidDepartmentList($departments, $allowedDepartments){ $result = []; $managedDepartments = []; if($departments == null) $departments = []; - foreach ($user->sharedDepartmentList->toArray() as $department) { + foreach ($allowedDepartments as $department) { array_push($managedDepartments,$department['id']); } $result = array_intersect($departments,$managedDepartments); diff --git a/server/libs/validations/validPrioritys.php b/server/libs/validations/validPrioritys.php deleted file mode 100644 index 53bf9505..00000000 --- a/server/libs/validations/validPrioritys.php +++ /dev/null @@ -1,19 +0,0 @@ -= 1 and ticket.date <= 2) GROUP BY ticket.id' ); } - /* + public function testDepartmentsFilter() { $this->assertEquals( $this->searchController->getSQLQuery([ - 'departments' => null + 'departments' => null, + 'allowedDepartments' => [ + [ + 'id' => 2 + ], + [ + 'id' => 1 + ], + [ + 'id' => 3 + ] + ] ]), - 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) GROUP BY ticket.id' + 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ( ticket.department_id = 2 or ticket.department_id = 1 or ticket.department_id = 3) GROUP BY ticket.id' ); $this->assertEquals( $this->searchController->getSQLQuery([ - 'departments' => [1] + 'departments' => [1], + 'allowedDepartments' => [ + [ + 'id' => 2 + ], + [ + 'id' => 1 + ], + [ + 'id' => 3 + ] + ] ]), 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ( ticket.department_id = 1) GROUP BY ticket.id' ); $this->assertEquals( $this->searchController->getSQLQuery([ - 'departments' => [1,2,3] + 'departments' => [1,2,3], + 'allowedDepartments' => [ + [ + 'id' => 2 + ], + [ + 'id' => 1 + ], + [ + 'id' => 3 + ] + ] ]), 'FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE ( ticket.department_id = 1 or ticket.department_id = 2 or ticket.department_id = 3) GROUP BY ticket.id' ); } - */ + public function testAuthorsFilter() { $this->assertEquals( $this->searchController->getSQLQuery([ @@ -228,7 +261,8 @@ class SearchControllerTest extends TestCase { $this->searchController->getSQLQuery([ 'query' => 'hello world' ]), - "FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE (ticket.title LIKE '%hello world%' or ticket.content LIKE '%hello world%' or ticket.ticket_number LIKE '%hello world%' or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%hello world%') ) GROUP BY ticket.id" + "FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE (ticket.title LIKE :query or ticket.content LIKE :query or ticket.ticket_number LIKE :query or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE :query) ) GROUP BY ticket.id" + ); } public function testQueryWithOrder() { @@ -244,7 +278,7 @@ class SearchControllerTest extends TestCase { 'page' => 1, 'query' => 'stark' ]), - "SELECT ticket.id FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE (ticket.title LIKE '%stark%' or ticket.content LIKE '%stark%' or ticket.ticket_number LIKE '%stark%' or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%stark%') ) GROUP BY ticket.id ORDER BY CASE WHEN (ticket.ticket_number LIKE '%stark%') THEN ticket.ticket_number END desc,CASE WHEN (ticket.title LIKE '%stark%') THEN ticket.title END desc, CASE WHEN ( ticket.content LIKE '%stark%') THEN ticket.content END desc, CASE WHEN (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%stark%') THEN ticketevent.content END desc,ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.priority desc, ticket.date desc LIMIT 10 OFFSET 0" + "SELECT ticket.id FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE (ticket.title LIKE :query or ticket.content LIKE :query or ticket.ticket_number LIKE :query or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE :query) ) GROUP BY ticket.id ORDER BY CASE WHEN (ticket.ticket_number LIKE '%stark%') THEN ticket.ticket_number END desc,CASE WHEN (ticket.title LIKE '%stark%') THEN ticket.title END desc, CASE WHEN ( ticket.content LIKE '%stark%') THEN ticket.content END desc, CASE WHEN (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%stark%') THEN ticketevent.content END desc,ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.priority desc, ticket.date desc LIMIT 10 OFFSET 0" ); $this->assertEquals( From d25da2c5ff055d0575bd88c99347a16d68ace8af Mon Sep 17 00:00:00 2001 From: Guillermo Date: Fri, 27 Dec 2019 19:50:50 -0300 Subject: [PATCH 14/19] add validation test --- client/src/data/languages/en.js | 2 +- server/controllers/ticket/search.php | 6 +++--- server/tests/controllers/ticket/searchTest.php | 2 +- tests/init.rb | 1 + 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index f244d610..7816e9c3 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -298,7 +298,7 @@ export default { 'MY_TICKETS_DESCRIPTION': 'Here you can view the tickets you are responsible for.', 'NEW_TICKETS_DESCRIPTION': 'Here you can view all the new tickets that are not assigned by anyone.', 'ALL_TICKETS_DESCRIPTION': 'Here you can view the tickets of the departments you are assigned.', - 'SEARCH_TICKETS_DESCRIPTION': 'Here you can search tickets by specifics filters.', + 'SEARCH_TICKETS_DESCRIPTION': 'Here you can search tickets by specific filters', 'TICKET_VIEW_DESCRIPTION': 'This ticket has been sent by a customer. Here you can respond or assign the ticket', 'BAN_USERS_DESCRIPTION': 'Here you can see a list of banned emails, you can un-ban them or add more emails to the list.', 'LIST_USERS_DESCRIPTION': 'This is the list of users that are registered in this platform. You can search for someone in particular, delete it or ban it.', diff --git a/server/controllers/ticket/search.php b/server/controllers/ticket/search.php index 3eb05304..e1fe5696 100644 --- a/server/controllers/ticket/search.php +++ b/server/controllers/ticket/search.php @@ -91,7 +91,7 @@ class SearchController extends Controller { 'error' => ERRORS::INVALID_ASSIGNED_FILTER ], 'orderBy' => [ - 'validation' => DataValidator::oneOf(DataValidator::ValidOrderBy(),DataValidator::nullType()), + 'validation' => DataValidator::oneOf(DataValidator::validOrderBy(),DataValidator::nullType()), 'error' => ERRORS::INVALID_ORDER_BY ], ] @@ -340,8 +340,8 @@ class SearchController extends Controller { $ticketEventTableExists = RedBean::exec("select table_name from information_schema.tables where table_name = 'ticketevent';"); if($querysearch != null){ - $ticketeventOrder = ( $ticketEventTableExists ? " CASE WHEN (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%".$querysearch."%') THEN ticketevent.content END desc," : ""); - $order .= "CASE WHEN (ticket.ticket_number LIKE '%" . $querysearch ."%') THEN ticket.ticket_number END desc,CASE WHEN (ticket.title LIKE '%" . $querysearch ."%') THEN ticket.title END desc, CASE WHEN ( ticket.content LIKE '%" . $querysearch ."%') THEN ticket.content END desc," . $ticketeventOrder ; + $ticketeventOrder = ( $ticketEventTableExists ? " CASE WHEN (ticketevent.type = 'COMMENT' and ticketevent.content LIKE :query) THEN ticketevent.content END desc," : ""); + $order .= "CASE WHEN (ticket.ticket_number LIKE :query) THEN ticket.ticket_number END desc,CASE WHEN (ticket.title LIKE :query) THEN ticket.title END desc, CASE WHEN ( ticket.content LIKE :query) THEN ticket.content END desc," . $ticketeventOrder ; } } diff --git a/server/tests/controllers/ticket/searchTest.php b/server/tests/controllers/ticket/searchTest.php index b402a81d..6f74449a 100644 --- a/server/tests/controllers/ticket/searchTest.php +++ b/server/tests/controllers/ticket/searchTest.php @@ -278,7 +278,7 @@ class SearchControllerTest extends TestCase { 'page' => 1, 'query' => 'stark' ]), - "SELECT ticket.id FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE (ticket.title LIKE :query or ticket.content LIKE :query or ticket.ticket_number LIKE :query or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE :query) ) GROUP BY ticket.id ORDER BY CASE WHEN (ticket.ticket_number LIKE '%stark%') THEN ticket.ticket_number END desc,CASE WHEN (ticket.title LIKE '%stark%') THEN ticket.title END desc, CASE WHEN ( ticket.content LIKE '%stark%') THEN ticket.content END desc, CASE WHEN (ticketevent.type = 'COMMENT' and ticketevent.content LIKE '%stark%') THEN ticketevent.content END desc,ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.priority desc, ticket.date desc LIMIT 10 OFFSET 0" + "SELECT ticket.id FROM (ticket LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id) WHERE (ticket.title LIKE :query or ticket.content LIKE :query or ticket.ticket_number LIKE :query or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE :query) ) GROUP BY ticket.id ORDER BY CASE WHEN (ticket.ticket_number LIKE :query) THEN ticket.ticket_number END desc,CASE WHEN (ticket.title LIKE :query) THEN ticket.title END desc, CASE WHEN ( ticket.content LIKE :query) THEN ticket.content END desc, CASE WHEN (ticketevent.type = 'COMMENT' and ticketevent.content LIKE :query) THEN ticketevent.content END desc,ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.priority desc, ticket.date desc LIMIT 10 OFFSET 0" ); $this->assertEquals( diff --git a/tests/init.rb b/tests/init.rb index ffffdcb7..e86faea2 100644 --- a/tests/init.rb +++ b/tests/init.rb @@ -71,4 +71,5 @@ require './ticket/add-tag.rb' require './ticket/delete-tag.rb' require './ticket/edit-comment.rb' require './system/disable-user-system.rb' +require './ticket/search.rb' # require './system/get-stats.rb' From 9f84239c3e5b162cbd64cf24bc46ecab06193f07 Mon Sep 17 00:00:00 2001 From: Guillermo Date: Fri, 27 Dec 2019 19:59:23 -0300 Subject: [PATCH 15/19] search ruby tests --- tests/ticket/search.rb | 114 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 tests/ticket/search.rb diff --git a/tests/ticket/search.rb b/tests/ticket/search.rb new file mode 100644 index 00000000..4b3e4c0a --- /dev/null +++ b/tests/ticket/search.rb @@ -0,0 +1,114 @@ +describe '/ticket/search' do + request('/user/logout') + Scripts.login($staff[:email], $staff[:password], true) + + + it 'should fail if the page is invalid' do + result = request('/ticket/search', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + page: -1 + }) + (result['status']).should.equal('fail') + (result['message']).should.equal('INVALID_PAGE') + end + + it 'should fail if the tags are invalid' do + result = request('/ticket/search', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + page: 1, + tags: [1,11,111,1111,11111,111111,1111111,11111111] + }) + (result['status']).should.equal('fail') + (result['message']).should.equal('INVALID_TAG_FILTER') + end + + it 'should fail if the closed value is invalid' do + result = request('/ticket/search', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + page: 1, + closed: 3 + }) + (result['status']).should.equal('fail') + (result['message']).should.equal('INVALID_CLOSED_FILTER') + end + + it 'should fail if the unreadStaff value is invalid' do + result = request('/ticket/search', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + page: 1, + unreadStaff: 3 + }) + (result['status']).should.equal('fail') + (result['message']).should.equal('INVALID_UNREAD_STAFF_FILTER') + end + + it 'should fail if the priority values are invalid' do + result = request('/ticket/search', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + page: 1, + priority: [0,1,5,6] + }) + (result['status']).should.equal('fail') + (result['message']).should.equal('INVALID_PRIORITY_FILTER') + end + + it 'should fail if the dateRange values are invalid' do + result = request('/ticket/search', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + page: 1, + dateRange: [11,69,11] + }) + (result['status']).should.equal('fail') + (result['message']).should.equal('INVALID_DATE_RANGE_FILTER') + end + + it 'should fail if the departments are invalid' do + result = request('/ticket/search', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + page: 1, + departments: [-1,-2,99] + }) + (result['status']).should.equal('fail') + (result['message']).should.equal('INVALID_DEPARTMENT_FILTER') + end + + it 'should fail if the authors are invalid' do + result = request('/ticket/search', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + page: 1, + authors: [{id:30001, staff: 1},{id:30,staff: 3}] + }) + (result['status']).should.equal('fail') + (result['message']).should.equal('INVALID_AUTHOR_FILTER') + end + + it 'should fail if the assigned value is invalid' do + result = request('/ticket/search', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + page: 1, + assigned: 3 + }) + (result['status']).should.equal('fail') + (result['message']).should.equal('INVALID_ASSIGNED_FILTER') + end + + it 'should fail if the orderBy values are invalid' do + result = request('/ticket/search', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + page: 1, + orderBy: [{value: 'closeddd', asc: 11}] + }) + (result['status']).should.equal('fail') + (result['message']).should.equal('INVALID_ORDER_BY') + end +end From e64e8e65f165b335d77514b4b7eb844feaffec61 Mon Sep 17 00:00:00 2001 From: Guillermo Date: Fri, 27 Dec 2019 20:51:22 -0300 Subject: [PATCH 16/19] update rudy test --- tests/ticket/search.rb | 43 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/tests/ticket/search.rb b/tests/ticket/search.rb index 4b3e4c0a..ad22f081 100644 --- a/tests/ticket/search.rb +++ b/tests/ticket/search.rb @@ -18,7 +18,7 @@ describe '/ticket/search' do csrf_userid: $csrf_userid, csrf_token: $csrf_token, page: 1, - tags: [1,11,111,1111,11111,111111,1111111,11111111] + tags: "[1,11,111,1111,11111,111111,1111111,11111111]" }) (result['status']).should.equal('fail') (result['message']).should.equal('INVALID_TAG_FILTER') @@ -51,7 +51,18 @@ describe '/ticket/search' do csrf_userid: $csrf_userid, csrf_token: $csrf_token, page: 1, - priority: [0,1,5,6] + priority: "[0,1,5,6]" + }) + (result['status']).should.equal('fail') + (result['message']).should.equal('INVALID_PRIORITY_FILTER') + end + + it 'should fail if the priority' do + result = request('/ticket/search', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + page: 1, + priority: "[0,1,),hi]" }) (result['status']).should.equal('fail') (result['message']).should.equal('INVALID_PRIORITY_FILTER') @@ -62,7 +73,7 @@ describe '/ticket/search' do csrf_userid: $csrf_userid, csrf_token: $csrf_token, page: 1, - dateRange: [11,69,11] + dateRange: "[11,69,()) ]" }) (result['status']).should.equal('fail') (result['message']).should.equal('INVALID_DATE_RANGE_FILTER') @@ -73,7 +84,7 @@ describe '/ticket/search' do csrf_userid: $csrf_userid, csrf_token: $csrf_token, page: 1, - departments: [-1,-2,99] + departments: "[-1,-2,99]" }) (result['status']).should.equal('fail') (result['message']).should.equal('INVALID_DEPARTMENT_FILTER') @@ -84,7 +95,16 @@ describe '/ticket/search' do csrf_userid: $csrf_userid, csrf_token: $csrf_token, page: 1, - authors: [{id:30001, staff: 1},{id:30,staff: 3}] + authors: "[{id:30001, staff: 1},{id:30,staff: 3}]" + }) + (result['status']).should.equal('fail') + (result['message']).should.equal('INVALID_AUTHOR_FILTER') + + result = request('/ticket/search', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + page: 1, + authors: "[{id:'delete all)', staff: 1},{id:30,staff: 3}]" }) (result['status']).should.equal('fail') (result['message']).should.equal('INVALID_AUTHOR_FILTER') @@ -101,12 +121,23 @@ describe '/ticket/search' do (result['message']).should.equal('INVALID_ASSIGNED_FILTER') end + it 'should fail if the assigned value is invalid' do + result = request('/ticket/search', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + page: 1, + query: 'dasjfawj!!!)())' + }) + (result['status']).should.equal('fail') + (result['message']).should.equal('INVALID_ASSIGNED_FILTER') + end + it 'should fail if the orderBy values are invalid' do result = request('/ticket/search', { csrf_userid: $csrf_userid, csrf_token: $csrf_token, page: 1, - orderBy: [{value: 'closeddd', asc: 11}] + orderBy: "{value: 'closeddd', asc: 11}" }) (result['status']).should.equal('fail') (result['message']).should.equal('INVALID_ORDER_BY') From 702b7862028acfc2ce394c388a0e011ad58bed62 Mon Sep 17 00:00:00 2001 From: Guillermo Date: Fri, 27 Dec 2019 22:46:25 -0300 Subject: [PATCH 17/19] search ruby test --- tests/ticket/search.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ticket/search.rb b/tests/ticket/search.rb index ad22f081..2ae320d6 100644 --- a/tests/ticket/search.rb +++ b/tests/ticket/search.rb @@ -126,7 +126,7 @@ describe '/ticket/search' do csrf_userid: $csrf_userid, csrf_token: $csrf_token, page: 1, - query: 'dasjfawj!!!)())' + assigned: 11113 }) (result['status']).should.equal('fail') (result['message']).should.equal('INVALID_ASSIGNED_FILTER') From 8be43bb7ead604d33f77cd6ffb95f989ddc48202 Mon Sep 17 00:00:00 2001 From: Guillermo Date: Sat, 28 Dec 2019 17:50:11 -0300 Subject: [PATCH 18/19] resolve mirrors errors --- server/controllers/ticket/search.php | 24 ++++++++++----------- server/libs/validations/validDateRange.php | 22 +++++++++---------- server/libs/validations/validOrderBy.php | 9 +++----- server/libs/validations/validPriorities.php | 4 ++-- 4 files changed, 28 insertions(+), 31 deletions(-) diff --git a/server/controllers/ticket/search.php b/server/controllers/ticket/search.php index e1fe5696..00431c34 100644 --- a/server/controllers/ticket/search.php +++ b/server/controllers/ticket/search.php @@ -195,19 +195,19 @@ class SearchController extends Controller { } } public function setClosedFilter($closed, &$filters){ - if ($closed != null) { + if ($closed !== null) { if ($filters != "") $filters .= " and "; $filters .= "ticket.closed = " . $closed ; } } private function setSeenFilter($unreadStaff, &$filters){ - if ($unreadStaff != null) { + if ($unreadStaff !== null) { if ($filters != "") $filters .= " and "; $filters .= "ticket.unread_staff = " . $unreadStaff; } } private function setPriorityFilter($priorities, &$filters){ - if($priorities != null){ + if($priorities !== null){ $first = TRUE; if ($filters != "") $filters .= " and "; foreach(array_unique($priorities) as $priority) { @@ -220,11 +220,11 @@ class SearchController extends Controller { } if($priority == 0){ - $filters .= "ticket.priority = " . "'low'"; + $filters .= "ticket.priority = 'low'"; }elseif($priority == 1){ - $filters .= "ticket.priority = " . "'medium'"; + $filters .= "ticket.priority = 'medium'"; }elseif($priority == 2){ - $filters .= "ticket.priority = " . "'high'"; + $filters .= "ticket.priority = 'high'"; } @@ -235,7 +235,7 @@ class SearchController extends Controller { } private function setDateFilter($dateRange, &$filters){ - if ($dateRange != null) { + if ($dateRange !== null) { if ($filters != "") $filters .= " and "; foreach($dateRange as $key => $date) { @@ -263,7 +263,7 @@ class SearchController extends Controller { } private function setAuthorFilter($authors, &$filters){ - if($authors != null){ + if($authors !== null){ $first = TRUE; if ($filters != "") $filters .= " and "; @@ -289,7 +289,7 @@ class SearchController extends Controller { } private function setAssignedFilter($assigned, &$filters){ - if($assigned != null){ + if($assigned !== null){ if ($filters != "") $filters .= " and "; $key = ""; $assigned == 0 ? $key = "IS NULL" : $key = "IS NOT NULL"; @@ -300,7 +300,7 @@ class SearchController extends Controller { private function setStringFilter($search, &$filters){ $ticketEventTableExists = RedBean::exec("select table_name from information_schema.tables where table_name = 'ticketevent';"); - if($search != null){ + if($search !== null){ if ($filters != "") $filters .= " and "; $ticketevent = ( $ticketEventTableExists ? " or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE :query)" : ""); $filters .= " (ticket.title LIKE :query or ticket.content LIKE :query or ticket.ticket_number LIKE :query". $ticketevent ." )"; @@ -331,7 +331,7 @@ class SearchController extends Controller { $order .= "ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.priority desc, ticket.date desc "; } private function setEspecificOrder($orderBy, &$order){ - if($orderBy != null){ + if($orderBy !== null){ $orientation = ($orderBy['asc'] ? " asc" : " desc" ); $order .= "ticket." . $orderBy['value'] . $orientation . ","; }; @@ -339,7 +339,7 @@ class SearchController extends Controller { private function setStringOrder($querysearch, &$order){ $ticketEventTableExists = RedBean::exec("select table_name from information_schema.tables where table_name = 'ticketevent';"); - if($querysearch != null){ + if($querysearch !== null){ $ticketeventOrder = ( $ticketEventTableExists ? " CASE WHEN (ticketevent.type = 'COMMENT' and ticketevent.content LIKE :query) THEN ticketevent.content END desc," : ""); $order .= "CASE WHEN (ticket.ticket_number LIKE :query) THEN ticket.ticket_number END desc,CASE WHEN (ticket.title LIKE :query) THEN ticket.title END desc, CASE WHEN ( ticket.content LIKE :query) THEN ticket.content END desc," . $ticketeventOrder ; } diff --git a/server/libs/validations/validDateRange.php b/server/libs/validations/validDateRange.php index 05f6a3c2..b332909e 100644 --- a/server/libs/validations/validDateRange.php +++ b/server/libs/validations/validDateRange.php @@ -7,15 +7,15 @@ use Respect\Validation\Rules\AbstractRule; class ValidDateRange extends AbstractRule { public function validate($dateRange) { - $dateArray = json_decode($dateRange); - $counter = 0; - if(is_array($dateArray)){ - foreach ($dateArray as $date) { - if (is_numeric($date)) $counter++; - } + $dateArray = json_decode($dateRange); + $length = count($dateArray); - return ((sizeof($dateArray) == 2 && $counter == 2) || sizeof($dateArray) == 0 ); - } - return false; - } -} \ No newline at end of file + if(is_array($dateArray) && $length == 2 ){ + foreach ($dateArray as $date) { + if (!is_numeric($date)) return false; + } + return $dateArray[0] <= $dateArray[1]; + } + return false; + } +} diff --git a/server/libs/validations/validOrderBy.php b/server/libs/validations/validOrderBy.php index 44466805..40babc27 100644 --- a/server/libs/validations/validOrderBy.php +++ b/server/libs/validations/validOrderBy.php @@ -8,15 +8,12 @@ class ValidOrderBy extends AbstractRule { public function validate($orderBy) { if(is_object(json_decode($orderBy))){ $values =["closed","owner_id","unread_staff","priority","date"]; - $isTrue = false; + $object = json_decode($orderBy); - if($object->asc !== 1 && $object->asc !== 0) return false; + if(($object->asc !== 1 && $object->asc !== 0) || !in_array($object->value, $values)) return false; - foreach ($values as $value) { - if($object->value == $value) $isTrue = true; - } - return $isTrue; + return true; } } } diff --git a/server/libs/validations/validPriorities.php b/server/libs/validations/validPriorities.php index 7313deec..aa3ba658 100644 --- a/server/libs/validations/validPriorities.php +++ b/server/libs/validations/validPriorities.php @@ -5,8 +5,8 @@ namespace CustomValidations; use Respect\Validation\Rules\AbstractRule; class ValidPriorities extends AbstractRule { - public function validate($prioritys) { - $PriorityList = json_decode($prioritys); + public function validate($priorities) { + $PriorityList = json_decode($priorities); if(is_array($PriorityList)){ foreach (array_unique($PriorityList) as $priorityId) { From cc9c51b85627de371c93b3590d17dda2d3dbf15c Mon Sep 17 00:00:00 2001 From: Guillermo Date: Sun, 29 Dec 2019 15:48:57 -0300 Subject: [PATCH 19/19] fix date range validation on php 7.2 --- server/libs/validations/validDateRange.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/server/libs/validations/validDateRange.php b/server/libs/validations/validDateRange.php index b332909e..c2bb3f05 100644 --- a/server/libs/validations/validDateRange.php +++ b/server/libs/validations/validDateRange.php @@ -8,9 +8,8 @@ class ValidDateRange extends AbstractRule { public function validate($dateRange) { $dateArray = json_decode($dateRange); - $length = count($dateArray); - - if(is_array($dateArray) && $length == 2 ){ + + if(is_array($dateArray) && count($dateArray) == 2 ){ foreach ($dateArray as $date) { if (!is_numeric($date)) return false; }