commit
9f4a293107
|
@ -274,4 +274,4 @@ export default connect((store) => {
|
|||
return {
|
||||
tags: store.config['tags']
|
||||
};
|
||||
})(TicketList);
|
||||
})(TicketList);
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
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();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.props.customList.title !== prevProps.customList.title) {
|
||||
this.getTickets();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
{(this.state.error) ? <Message type="error">{i18n('ERROR_RETRIEVING_TICKETS')}</Message> : <TicketList {...this.getTicketListProps()}/>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
getTickets() {
|
||||
this.setState({
|
||||
loading:true
|
||||
})
|
||||
API.call({
|
||||
path: '/ticket/search',
|
||||
data: {
|
||||
page : this.state.page,
|
||||
...this.props.customList.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);
|
|
@ -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 (
|
|||
<Route path="my-tickets" component={AdminPanelMyTickets} />
|
||||
<Route path="new-tickets" component={AdminPanelNewTickets} />
|
||||
<Route path="all-tickets" component={AdminPanelAllTickets} />
|
||||
<Route path="search-tickets" component={AdminPanelSearchTickets} />
|
||||
<Route path="custom-responses" component={AdminPanelCustomResponses} />
|
||||
<Route path="view-ticket/:ticketNumber" component={AdminPanelViewTicket} />
|
||||
</Route>
|
||||
|
|
|
@ -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(_.without([
|
||||
{
|
||||
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
|
||||
])
|
||||
},
|
||||
this.props.config['user-system-enabled'] ? {
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
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 (
|
||||
<div className="admin-panel-all-tickets">
|
||||
<Header title={i18n('ALL_TICKETS')} description={i18n('SEARCH_TICKETS_DESCRIPTION')} />
|
||||
{(this.props.error) ? <Message type="error">{i18n('ERROR_RETRIEVING_TICKETS')}</Message> : <TicketQueryList customList ={this.getFilters()}/>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
getFilters() {
|
||||
let customList = window.customTicketList[this.props.location.query.custom*1] ? window.customTicketList[this.props.location.query.custom*1] : null
|
||||
return {
|
||||
...customList
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default connect((store) => {
|
||||
return {
|
||||
error: store.adminData.allTicketsError
|
||||
};
|
||||
})(AdminPanelSearchTickets);
|
|
@ -140,4 +140,4 @@ class Menu extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
export default Menu;
|
||||
export default Menu;
|
||||
|
|
|
@ -201,4 +201,4 @@ $transition: background-color 0.3s ease, color 0.3s ease;
|
|||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,4 +98,4 @@ class Pagination extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
export default Pagination;
|
||||
export default Pagination;
|
||||
|
|
|
@ -55,7 +55,7 @@ class Table extends React.Component {
|
|||
'table__header-column': true,
|
||||
[header.className]: (header.className)
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<th className={classNames(classes)} key={header.key}>
|
||||
{header.value}
|
||||
|
@ -97,7 +97,7 @@ class Table extends React.Component {
|
|||
};
|
||||
|
||||
return (
|
||||
|
||||
|
||||
<td className={classNames(classes)} key={key}>{row[key]}</td>
|
||||
);
|
||||
}
|
||||
|
@ -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;
|
||||
export default Table;
|
||||
|
|
|
@ -94,6 +94,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...',
|
||||
|
@ -297,6 +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 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.',
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
<script src="/config.js"></script>
|
||||
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=String.prototype.startsWith,Array.from,Array.prototype.fill,Array.prototype.keys,Array.prototype.find,Array.prototype.findIndex,Array.prototype.includes,String.prototype.repeat,Number.isInteger,Promise&flags=gated"></script>
|
||||
</body>
|
||||
|
|
|
@ -50,7 +50,7 @@ class GetAllTicketsStaffController extends Controller {
|
|||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Response::respondSuccess([
|
||||
'tickets' => $this->getTicketList()->toArray(true),
|
||||
'pages' => $this->getTotalPages()
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -0,0 +1,348 @@
|
|||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
use RedBeanPHP\Facade as RedBean;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/search Search tickets
|
||||
* @apiVersion 4.5.0
|
||||
*
|
||||
* @apiName Search ticket
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path search specific tickets.
|
||||
*
|
||||
* @apiPermission user
|
||||
*
|
||||
* @apiParam {Number[]} tags The ids of the tags to make a custom search.
|
||||
* @apiParam {Number} closed The status of closed 1 or 0 to make a custom search.
|
||||
* @apiParam {Number} unreadStaff The status of unread_staff 1 or 0 to make a custom search.
|
||||
* @apiParam {Number[]} priority The values of priority to make a custom search.
|
||||
* @apiParam {Number[]} dateRange The numbers of the range of date to make a custom search.
|
||||
* @apiParam {Number[]} departments The ids of the departments to make a custom search.
|
||||
* @apiParam {Object[]} authors A object {id,staff} with id and boolean to make a custom search.
|
||||
* @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.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TAG_FILTER
|
||||
* @apiUse INVALID_CLOSED_FILTER
|
||||
* @apiUse INVALID_UNREAD_STAFF_FILTER
|
||||
* @apiUse INVALID_PRIORITY_FILTER
|
||||
* @apiUse INVALID_DATE_RANGE_FILTER
|
||||
* @apiUse INVALID_DEPARTMENT_FILTER
|
||||
* @apiUse INVALID_AUTHOR_FILTER
|
||||
* @apiUse INVALID_ASSIGNED_FILTER
|
||||
* @apiUse INVALID_ORDER_BY
|
||||
* @apiUse INVALID_PAGE
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*
|
||||
|
||||
*/
|
||||
|
||||
class SearchController extends Controller {
|
||||
const PATH = '/search';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'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::validPriorities(),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() {
|
||||
$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'),
|
||||
'allowedDepartments' => Controller::getLoggedUser()->sharedDepartmentList->toArray(),
|
||||
];
|
||||
|
||||
|
||||
$query = $this->getSQLQuery($inputs);
|
||||
$queryWithOrder = $this->getSQLQueryWithOrder($inputs);
|
||||
$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,
|
||||
'pages' => ceil($totalCount / 10),
|
||||
'page' => $inputs['page'] ? ($inputs['page']*1) : 1
|
||||
]);
|
||||
}else{
|
||||
Response::respondSuccess([]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function getSQLQuery($inputs) {
|
||||
$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";
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function getSQLQueryWithOrder($inputs) {
|
||||
$query = $this->getSQLQuery($inputs);
|
||||
$order = "";
|
||||
$query = "SELECT" . " ticket.id " . $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'],$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;
|
||||
}
|
||||
|
||||
private function setTagFilter($tagList, &$filters){
|
||||
$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) {
|
||||
|
||||
$key == 0 ? $filters .= " ( " : null;
|
||||
($key != 0 && $key != sizeof($tagList)) ? $filters .= " or " : null;
|
||||
|
||||
$filters .= "tag_ticket.tag_id = " . $tag ;
|
||||
}
|
||||
$filters .= ")";
|
||||
}
|
||||
}
|
||||
public function setClosedFilter($closed, &$filters){
|
||||
if ($closed !== null) {
|
||||
if ($filters != "") $filters .= " and ";
|
||||
$filters .= "ticket.closed = " . $closed ;
|
||||
}
|
||||
}
|
||||
private function setSeenFilter($unreadStaff, &$filters){
|
||||
if ($unreadStaff !== null) {
|
||||
if ($filters != "") $filters .= " and ";
|
||||
$filters .= "ticket.unread_staff = " . $unreadStaff;
|
||||
}
|
||||
}
|
||||
private function setPriorityFilter($priorities, &$filters){
|
||||
if($priorities !== null){
|
||||
$first = TRUE;
|
||||
if ($filters != "") $filters .= " and ";
|
||||
foreach(array_unique($priorities) as $priority) {
|
||||
|
||||
if($first){
|
||||
$filters .= " ( ";
|
||||
$first = FALSE;
|
||||
} else {
|
||||
$filters .= " or ";
|
||||
}
|
||||
|
||||
if($priority == 0){
|
||||
$filters .= "ticket.priority = 'low'";
|
||||
}elseif($priority == 1){
|
||||
$filters .= "ticket.priority = 'medium'";
|
||||
}elseif($priority == 2){
|
||||
$filters .= "ticket.priority = 'high'";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
$priorities != "" ? $filters .= ") " : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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($departments,$allowedDepartments, &$filters){
|
||||
$validDepartments = $this->generateValidDepartmentList($departments, $allowedDepartments);
|
||||
if ($filters != "") $filters .= " and ";
|
||||
$first = TRUE;
|
||||
|
||||
foreach($validDepartments as $department) {
|
||||
if($first){
|
||||
$filters .= " ( ";
|
||||
$first = FALSE;
|
||||
} else {
|
||||
$filters .= " or ";
|
||||
}
|
||||
$filters .= "ticket.department_id = " . $department;
|
||||
}
|
||||
$filters .= ")";
|
||||
|
||||
}
|
||||
|
||||
private function setAuthorFilter($authors, &$filters){
|
||||
if($authors !== null){
|
||||
$first = TRUE;
|
||||
if ($filters != "") $filters .= " and ";
|
||||
|
||||
foreach($authors as $author){
|
||||
|
||||
if($first){
|
||||
$filters .= " ( ";
|
||||
$first = FALSE;
|
||||
} else {
|
||||
$filters .= " or ";
|
||||
}
|
||||
|
||||
if($author['staff']){
|
||||
$filters .= "ticket.author_staff_id = " . $author['id'];
|
||||
} else {
|
||||
$filters .= "ticket.author_id = " . $author['id'];
|
||||
}
|
||||
}
|
||||
|
||||
$filters .= ")";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private function setAssignedFilter($assigned, &$filters){
|
||||
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($search, &$filters){
|
||||
$ticketEventTableExists = RedBean::exec("select table_name from information_schema.tables where table_name = 'ticketevent';");
|
||||
|
||||
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 ." )";
|
||||
};
|
||||
}
|
||||
|
||||
private function generateValidDepartmentList($departments, $allowedDepartments){
|
||||
$result = [];
|
||||
$managedDepartments = [];
|
||||
if($departments == null) $departments = [];
|
||||
foreach ($allowedDepartments 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 ";
|
||||
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($orderBy, &$order){
|
||||
if($orderBy !== null){
|
||||
$orientation = ($orderBy['asc'] ? " asc" : " desc" );
|
||||
$order .= "ticket." . $orderBy['value'] . $orientation . ",";
|
||||
};
|
||||
}
|
||||
private function setStringOrder($querysearch, &$order){
|
||||
$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 :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 ;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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';
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace CustomValidations;
|
||||
|
||||
use Respect\Validation\Rules\AbstractRule;
|
||||
|
||||
class ValidAuthorsId extends AbstractRule {
|
||||
|
||||
public function validate($authors) {
|
||||
if(is_array(json_decode($authors))){
|
||||
foreach (json_decode($authors) as $authorObject) {
|
||||
if($authorObject->staff){
|
||||
$author = \Staff::getDataStore($authorObject->id);
|
||||
}else{
|
||||
$author = \User::getDataStore($authorObject->id);
|
||||
}
|
||||
if($author->isNull()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace CustomValidations;
|
||||
|
||||
use Respect\Validation\Rules\AbstractRule;
|
||||
|
||||
class ValidDateRange extends AbstractRule {
|
||||
|
||||
public function validate($dateRange) {
|
||||
$dateArray = json_decode($dateRange);
|
||||
|
||||
if(is_array($dateArray) && count($dateArray) == 2 ){
|
||||
foreach ($dateArray as $date) {
|
||||
if (!is_numeric($date)) return false;
|
||||
}
|
||||
return $dateArray[0] <= $dateArray[1];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace CustomValidations;
|
||||
|
||||
use Respect\Validation\Rules\AbstractRule;
|
||||
|
||||
class ValidDepartmentsId extends AbstractRule {
|
||||
|
||||
public function validate($departments) {
|
||||
$DepartmentsList = json_decode($departments);
|
||||
if(is_array($DepartmentsList)){
|
||||
foreach ($DepartmentsList as $departmentsId) {
|
||||
$department = \Department::getDataStore($departmentsId);
|
||||
if($department->isNull()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace CustomValidations;
|
||||
|
||||
use Respect\Validation\Rules\AbstractRule;
|
||||
|
||||
class ValidOrderBy extends AbstractRule {
|
||||
public function validate($orderBy) {
|
||||
if(is_object(json_decode($orderBy))){
|
||||
$values =["closed","owner_id","unread_staff","priority","date"];
|
||||
|
||||
$object = json_decode($orderBy);
|
||||
|
||||
if(($object->asc !== 1 && $object->asc !== 0) || !in_array($object->value, $values)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace CustomValidations;
|
||||
|
||||
use Respect\Validation\Rules\AbstractRule;
|
||||
|
||||
class ValidPriorities extends AbstractRule {
|
||||
public function validate($priorities) {
|
||||
$PriorityList = json_decode($priorities);
|
||||
|
||||
if(is_array($PriorityList)){
|
||||
foreach (array_unique($PriorityList) as $priorityId) {
|
||||
if($priorityId != 0 && $priorityId != 1 && $priorityId != 2) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace CustomValidations;
|
||||
|
||||
use Respect\Validation\Rules\AbstractRule;
|
||||
|
||||
class ValidTagsId extends AbstractRule {
|
||||
|
||||
public function validate($tags) {
|
||||
$listTags = json_decode($tags);
|
||||
if(is_array($listTags)){
|
||||
foreach ($listTags as $TagId) {
|
||||
$tag = \Tag::getDataStore($TagId);
|
||||
if($tag->isNull()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,13 +1,19 @@
|
|||
<?php
|
||||
|
||||
class Controller {
|
||||
public static $requestReturnMock = 'mockRequestValue';
|
||||
const USE_VALUE_RETURN = 'sadf64a5s6d1f5sa';
|
||||
public static $requestReturnMock = null;
|
||||
public static $checkUserLoggedReturnMock = true;
|
||||
public static $isUserSystemEnabledReturnMock = true;
|
||||
|
||||
public static function useValueReturn() {
|
||||
static::$requestReturnMock = self::USE_VALUE_RETURN;
|
||||
}
|
||||
|
||||
public static function request($value) {
|
||||
if($value === 'staff') return false;
|
||||
return static::$requestReturnMock;
|
||||
if(static::$requestReturnMock !== self::USE_VALUE_RETURN) return static::$requestReturnMock;
|
||||
return $value . '_REQUEST_RESULT';
|
||||
}
|
||||
|
||||
public static function checkUserLogged() {
|
||||
|
|
|
@ -0,0 +1,292 @@
|
|||
<?php
|
||||
// MOCKS
|
||||
include_once 'tests/__lib__/Mock.php';
|
||||
include_once 'tests/__mocks__/NullDataStoreMock.php';
|
||||
include_once 'tests/__mocks__/ResponseMock.php';
|
||||
include_once 'tests/__mocks__/ControllerMock.php';
|
||||
include_once 'tests/__mocks__/SessionMock.php';
|
||||
include_once 'tests/__mocks__/UserMock.php';
|
||||
include_once 'tests/__mocks__/HashingMock.php';
|
||||
include_once 'tests/__mocks__/SessionCookieMock.php';
|
||||
include_once 'tests/__mocks__/RedBeanMock.php';
|
||||
include_once 'data/ERRORS.php';
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use RedBeanPHP\Facade as RedBean;
|
||||
|
||||
class SearchControllerTest extends TestCase {
|
||||
private $searchController;
|
||||
|
||||
protected function setUp() {
|
||||
Session::initStubs();
|
||||
Response::initStubs();
|
||||
RedBean::initStubs();
|
||||
RedBean::setStatics([
|
||||
'exec' => \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,
|
||||
'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 = 2 or ticket.department_id = 1 or ticket.department_id = 3) GROUP BY ticket.id'
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$this->searchController->getSQLQuery([
|
||||
'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],
|
||||
'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([
|
||||
'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 :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() {
|
||||
$this->assertEquals(
|
||||
$this->searchController->getSQLQueryWithOrder([
|
||||
'page' => 1
|
||||
]),
|
||||
"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(
|
||||
$this->searchController->getSQLQueryWithOrder([
|
||||
'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 :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(
|
||||
$this->searchController->getSQLQueryWithOrder([
|
||||
'page' => 1,
|
||||
'orderBy' => ['value' => 'closed', 'asc' => 1]
|
||||
]),
|
||||
"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"
|
||||
);
|
||||
}
|
||||
}
|
|
@ -35,9 +35,9 @@ class LoginControllerTest extends TestCase {
|
|||
|
||||
public function testShouldCreateSessionAndRespondSuccessIfCredentialsAreValid() {
|
||||
Session::mockInstanceFunction('sessionExists', \Mock::stub()->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',
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -10,14 +10,18 @@ describe'/staff/get-all' do
|
|||
|
||||
(result['status']).should.equal('success')
|
||||
|
||||
result['data'][0]['departments'] = result['data'][0]['departments'].sort_by do |department|
|
||||
department['id'].to_i
|
||||
end
|
||||
|
||||
(result['data'][0]['name']).should.equal('Emilia Clarke')
|
||||
(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)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
describe '/system/get-settings' do
|
||||
it 'should return correct values' do
|
||||
result = request('/system/get-settings')
|
||||
|
||||
|
||||
(result['status']).should.equal('success')
|
||||
(result['data']['language']).should.equal('en')
|
||||
(result['data']['departments'][0]['name']).should.equal('Help and Support')
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
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 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')
|
||||
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,()) ]"
|
||||
})
|
||||
(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')
|
||||
|
||||
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')
|
||||
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 assigned value is invalid' do
|
||||
result = request('/ticket/search', {
|
||||
csrf_userid: $csrf_userid,
|
||||
csrf_token: $csrf_token,
|
||||
page: 1,
|
||||
assigned: 11113
|
||||
})
|
||||
(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
|
Loading…
Reference in New Issue