From e9dfbfb97b91b4281f8c18bce43684f9fa6dfe4c Mon Sep 17 00:00:00 2001 From: Guillermo Date: Thu, 15 Nov 2018 20:51:44 -0300 Subject: [PATCH 1/7] wip --- .../src/app-components/department-dropdown.js | 31 +++++++++++++ client/src/app-components/ticket-list.js | 13 +++--- client/src/app-components/ticket-viewer.js | 16 ++++++- .../src/app/admin/panel/admin-panel-layout.js | 9 +++- .../app/admin/panel/staff/add-staff-modal.js | 11 ++++- .../panel/staff/admin-panel-departments.js | 18 ++++++-- .../panel/staff/admin-panel-departments.scss | 17 ++++++- .../panel/staff/admin-panel-staff-members.js | 12 ++--- .../staff/admin-panel-staff-members.scss | 5 +- .../src/app/admin/panel/staff/staff-editor.js | 8 +++- .../create-ticket-form.js | 5 +- client/src/data/languages/en.js | 1 + client/src/reducers/session-reducer.js | 9 ++-- server/controllers/staff/get.php | 7 +-- server/controllers/staff/un-assign-ticket.php | 8 +++- server/controllers/system/add-department.php | 12 ++++- server/controllers/system/edit-department.php | 15 +++--- server/controllers/system/get-settings.php | 4 +- .../controllers/ticket/change-department.php | 8 +++- server/controllers/ticket/create.php | 3 ++ server/models/Department.php | 46 ++++++++++++++----- tests/Makefile | 2 +- 22 files changed, 195 insertions(+), 65 deletions(-) create mode 100644 client/src/app-components/department-dropdown.js diff --git a/client/src/app-components/department-dropdown.js b/client/src/app-components/department-dropdown.js new file mode 100644 index 00000000..abc916b9 --- /dev/null +++ b/client/src/app-components/department-dropdown.js @@ -0,0 +1,31 @@ +import React from 'react'; +import {connect} from 'react-redux'; +import classNames from 'classnames'; + +import DropDown from 'core-components/drop-down'; +import Icon from 'core-components/icon'; + +class DepartmentDropdown extends React.Component { + static propTypes = { + value: React.PropTypes.number, + onChange: React.PropTypes.func, + departments: React.PropTypes.array + } + render(){ + return + } + + getDepartments(){ + let departments = this.props.departments.map((department) => { + if(department.private*1) { + return {content: {department.name} }; + }else{ + return {content: department.name}; + } + }); + + return departments; + } +} + +export default DepartmentDropdown; diff --git a/client/src/app-components/ticket-list.js b/client/src/app-components/ticket-list.js index c3d95be4..b0d144f3 100644 --- a/client/src/app-components/ticket-list.js +++ b/client/src/app-components/ticket-list.js @@ -5,10 +5,11 @@ import i18n from 'lib-app/i18n'; import DateTransformer from 'lib-core/date-transformer'; import TicketInfo from 'app-components/ticket-info'; +import DepartmentDropdown from 'app-components/department-dropdown'; import Table from 'core-components/table'; import Button from 'core-components/button'; import Tooltip from 'core-components/tooltip'; -import DropDown from 'core-components/drop-down'; +import Icon from 'core-components/icon'; class TicketList extends React.Component { static propTypes = { @@ -49,14 +50,14 @@ class TicketList extends React.Component { renderDepartmentsDropDown() { return (
- +
); } getDepartmentDropdownProps() { return { - items: this.getDepartments(), + departments: this.getDepartments(), onChange: (event) => { this.setState({ selectedDepartment: event.index && this.props.departments[event.index - 1].id @@ -80,12 +81,10 @@ class TicketList extends React.Component { } getDepartments() { - let departments = this.props.departments.map((department) => { - return {content: department.name}; - }); + let departments = _.clone(this.props.departments); departments.unshift({ - content: i18n('ALL_DEPARTMENTS') + name: i18n('ALL_DEPARTMENTS') }); return departments; diff --git a/client/src/app-components/ticket-viewer.js b/client/src/app-components/ticket-viewer.js index 6bab5566..22ec5e38 100644 --- a/client/src/app-components/ticket-viewer.js +++ b/client/src/app-components/ticket-viewer.js @@ -20,6 +20,7 @@ import Message from 'core-components/message'; import Icon from 'core-components/icon'; import TextEditor from 'core-components/text-editor'; import InfoTooltip from 'core-components/info-tooltip'; +import DepartmentDropdown from 'app-components/department-dropdown'; class TicketViewer extends React.Component { static propTypes = { @@ -86,6 +87,7 @@ class TicketViewer extends React.Component { renderEditableHeaders() { const ticket = this.props.ticket; const departments = SessionStore.getDepartments(); + const priorities = { 'low': 0, 'medium': 1, @@ -106,8 +108,8 @@ class TicketViewer extends React.Component {
- {return {content: department.name}})} +
@@ -299,6 +301,16 @@ class TicketViewer extends React.Component { } }; } + getPublicDepartments() { + var publicdepartments = Session.Store.getDepartments().map((department) => { + if(department.private*1){ + null; + }else { + department.name; + } + }); + return publicdepartments; + } onDepartmentDropdownChanged(event) { AreYouSure.openModal(null, this.changeDepartment.bind(this, event.index)); diff --git a/client/src/app/admin/panel/admin-panel-layout.js b/client/src/app/admin/panel/admin-panel-layout.js index 59a5e7d9..dbb70d16 100644 --- a/client/src/app/admin/panel/admin-panel-layout.js +++ b/client/src/app/admin/panel/admin-panel-layout.js @@ -1,4 +1,7 @@ import React from 'react'; +import store from 'app/store'; + +import ConfigActions from 'actions/config-actions'; import MainLayout from 'app/main/main-layout'; import AdminPanelStaffWidget from 'app/admin/panel/admin-panel-staff-widget'; @@ -8,6 +11,10 @@ import Widget from 'core-components/widget'; class AdminPanel extends React.Component { + componentDidMount() { + store.dispatch(ConfigActions.updateData()); + } + render() { return ( @@ -33,4 +40,4 @@ class AdminPanel extends React.Component { } } -export default AdminPanel; \ No newline at end of file +export default AdminPanel; diff --git a/client/src/app/admin/panel/staff/add-staff-modal.js b/client/src/app/admin/panel/staff/add-staff-modal.js index 16b230c3..8a20ed00 100644 --- a/client/src/app/admin/panel/staff/add-staff-modal.js +++ b/client/src/app/admin/panel/staff/add-staff-modal.js @@ -10,6 +10,7 @@ import Form from 'core-components/form'; import FormField from 'core-components/form-field'; import SubmitButton from 'core-components/submit-button'; import Button from 'core-components/button'; +import Icon from 'core-components/icon'; class AddStaffModal extends React.Component { @@ -63,7 +64,13 @@ class AddStaffModal extends React.Component { } getDepartments() { - return SessionStore.getDepartments().map(department => department.name); + return SessionStore.getDepartments().map(department => { + if(department.private*1){ + return {department.name} + }else { + return department.name; + } + }); } onSubmit(form) { @@ -112,4 +119,4 @@ class AddStaffModal extends React.Component { } } -export default AddStaffModal; \ No newline at end of file +export default AddStaffModal; diff --git a/client/src/app/admin/panel/staff/admin-panel-departments.js b/client/src/app/admin/panel/staff/admin-panel-departments.js index b602d9a1..4c4664a8 100644 --- a/client/src/app/admin/panel/staff/admin-panel-departments.js +++ b/client/src/app/admin/panel/staff/admin-panel-departments.js @@ -16,6 +16,7 @@ import Form from 'core-components/form'; import FormField from 'core-components/form-field'; import SubmitButton from 'core-components/submit-button'; import DropDown from 'core-components/drop-down'; +import Icon from 'core-components/icon'; class AdminPanelDepartments extends React.Component { static defaultProps = { @@ -44,7 +45,13 @@ class AdminPanelDepartments extends React.Component {
- +
+ +
+ + +
+
{i18n((this.state.selectedIndex !== -1) ? 'UPDATE_DEPARTMENT' : 'ADD_DEPARTMENT')} @@ -100,6 +107,7 @@ class AdminPanelDepartments extends React.Component { content: ( {department.name} + {department.private*1 ? : null } {(!department.owners) ? ( @@ -143,7 +151,8 @@ class AdminPanelDepartments extends React.Component { path: '/system/edit-department', data: { departmentId: this.getCurrentDepartment().id, - name: form.name + name: form.name, + private: form.private ? 1 : 0 } }).then(() => { this.setState({formLoading: false}); @@ -153,7 +162,8 @@ class AdminPanelDepartments extends React.Component { API.call({ path: '/system/add-department', data: { - name: form.name + name: form.name, + private: form.private ? 1 : 0 } }).then(() => { this.retrieveDepartments(); @@ -222,4 +232,4 @@ export default connect((store) => { return { departments: store.config.departments }; -})(AdminPanelDepartments); \ No newline at end of file +})(AdminPanelDepartments); diff --git a/client/src/app/admin/panel/staff/admin-panel-departments.scss b/client/src/app/admin/panel/staff/admin-panel-departments.scss index 33eec06e..2c0790a9 100644 --- a/client/src/app/admin/panel/staff/admin-panel-departments.scss +++ b/client/src/app/admin/panel/staff/admin-panel-departments.scss @@ -2,7 +2,6 @@ .admin-panel-departments { - &__list { position: relative; } @@ -12,6 +11,14 @@ min-width: 156px; } + &__name { + display:inline-block;margin-right: 101px; + } + &__private-option { + display:inline-block; + margin-left: 10px; + } + &__optional-buttons { float: right; } @@ -39,4 +46,10 @@ &__transfer-tickets-drop-down { display: inline-block; } -} \ No newline at end of file + &__private-icon { + margin-left: 5px; + } + &__info-tooltip { + margin-left: 2px; + } +} diff --git a/client/src/app/admin/panel/staff/admin-panel-staff-members.js b/client/src/app/admin/panel/staff/admin-panel-staff-members.js index 8458bd7c..ac587050 100644 --- a/client/src/app/admin/panel/staff/admin-panel-staff-members.js +++ b/client/src/app/admin/panel/staff/admin-panel-staff-members.js @@ -18,6 +18,7 @@ import DropDown from 'core-components/drop-down'; import Button from 'core-components/button'; import Icon from 'core-components/icon'; import Loading from 'core-components/loading'; +import DepartmentDropdown from 'app-components/department-dropdown'; class AdminPanelStaffMembers extends React.Component { @@ -45,7 +46,7 @@ class AdminPanelStaffMembers extends React.Component {
- + @@ -61,7 +62,7 @@ class AdminPanelStaffMembers extends React.Component { getDepartmentDropdownProps() { return { - items: this.getDepartments(), + departments: this.getDepartments(), onChange: (event) => { let departments = SessionStore.getDepartments(); this.setState({ @@ -97,12 +98,9 @@ class AdminPanelStaffMembers extends React.Component { } getDepartments() { - let departments = SessionStore.getDepartments().map((department) => { - return {content: department.name}; - }); - + let departments = _.clone(SessionStore.getDepartments()) departments.unshift({ - content: i18n('ALL_DEPARTMENTS') + name: i18n('ALL_DEPARTMENTS') }); return departments; diff --git a/client/src/app/admin/panel/staff/admin-panel-staff-members.scss b/client/src/app/admin/panel/staff/admin-panel-staff-members.scss index 94e8b0da..974d2183 100644 --- a/client/src/app/admin/panel/staff/admin-panel-staff-members.scss +++ b/client/src/app/admin/panel/staff/admin-panel-staff-members.scss @@ -23,4 +23,7 @@ text-decoration: none; } } -} \ No newline at end of file + &__private { + margin-left: 5px; + } +} diff --git a/client/src/app/admin/panel/staff/staff-editor.js b/client/src/app/admin/panel/staff/staff-editor.js index 8f2466bb..51d4e54b 100644 --- a/client/src/app/admin/panel/staff/staff-editor.js +++ b/client/src/app/admin/panel/staff/staff-editor.js @@ -256,7 +256,13 @@ class StaffEditor extends React.Component { } getDepartments() { - return SessionStore.getDepartments().map(department => department.name); + return SessionStore.getDepartments().map(department => { + if(department.private*1){ + return {department.name} + }else { + return department.name; + } + }); } getStaffLevelInfo() { diff --git a/client/src/app/main/dashboard/dashboard-create-ticket/create-ticket-form.js b/client/src/app/main/dashboard/dashboard-create-ticket/create-ticket-form.js index 4247f9a7..6d30bae1 100644 --- a/client/src/app/main/dashboard/dashboard-create-ticket/create-ticket-form.js +++ b/client/src/app/main/dashboard/dashboard-create-ticket/create-ticket-form.js @@ -8,6 +8,7 @@ import API from 'lib-app/api-call'; import SessionStore from 'lib-app/session-store'; import LanguageSelector from 'app-components/language-selector'; import Captcha from 'app/main/captcha'; +import DepartmentDropdown from 'app-components/department-dropdown'; import Header from 'core-components/header'; import TextEditor from 'core-components/text-editor'; @@ -48,8 +49,8 @@ class CreateTicketForm extends React.Component { {(!this.props.userLogged) ? this.renderEmailAndName() : null}
- {return {content: department.name}}), + $department->id, - 'name' => $department->name + 'name' => $department->name, + 'private' => $department->private ]; } @@ -72,4 +73,4 @@ class GetStaffController extends Controller { 'sendEmailOnNewTicket' => $user->sendEmailOnNewTicket ]); } -} \ No newline at end of file +} diff --git a/server/controllers/staff/un-assign-ticket.php b/server/controllers/staff/un-assign-ticket.php index a162d4d4..e138dd80 100755 --- a/server/controllers/staff/un-assign-ticket.php +++ b/server/controllers/staff/un-assign-ticket.php @@ -27,6 +27,12 @@ class UnAssignStaffController extends Controller { const PATH = '/un-assign-ticket'; const METHOD = 'POST'; + private $user; + + public function __construct($user=null) { + $this->user = $user; + } + public function validations() { return [ 'permission' => 'staff_1', @@ -41,7 +47,7 @@ class UnAssignStaffController extends Controller { public function handler() { $ticketNumber = Controller::request('ticketNumber'); - $user = Controller::getLoggedUser(); + $user = ($this->user? $this->user : Controller::getLoggedUser()); $ticket = Ticket::getByTicketNumber($ticketNumber); $owner = $ticket->owner; diff --git a/server/controllers/system/add-department.php b/server/controllers/system/add-department.php index be0ed503..bef23f88 100755 --- a/server/controllers/system/add-department.php +++ b/server/controllers/system/add-department.php @@ -14,6 +14,7 @@ use Respect\Validation\Validator as DataValidator; * @apiPermission staff3 * * @apiParam {String} name Name of the new department. + * @apiParam {Boolean} private Indicates if the deparment is not shown to users. * * @apiUse NO_PERMISSION * @@ -28,17 +29,24 @@ class AddDepartmentController extends Controller { public function validations() { return [ 'permission' => 'staff_3', - 'requestData' => [] + 'requestData' => [ + 'name' => [ + 'validation' => DataValidator::length(2, 100), + 'error' => ERRORS::INVALID_NAME + ] + ] ]; } public function handler() { $name = Controller::request('name'); + $private = Controller::request('private'); $departmentInstance = new Department(); $departmentInstance->setProperties([ - 'name' => $name, + 'name' => $name , + 'private' => $private ? 1 : 0 ]); $departmentInstance->store(); diff --git a/server/controllers/system/edit-department.php b/server/controllers/system/edit-department.php index 19de4de8..9e18b8b7 100755 --- a/server/controllers/system/edit-department.php +++ b/server/controllers/system/edit-department.php @@ -16,6 +16,7 @@ DataValidator::with('CustomValidations', true); * * @apiParam {String} name The new name of the department. * @apiParam {Number} departmentId The Id of the department. + * @apiParam {Boolean} private Indicates if the department is shown to users; * * @apiUse NO_PERMISSION * @apiUse INVALID_NAME @@ -33,10 +34,6 @@ class EditDepartmentController extends Controller { return [ 'permission' => 'staff_3', 'requestData' => [ - 'name' => [ - 'validation' => DataValidator::alnum(), - 'error' => ERRORS::INVALID_NAME - ], 'departmentId' => [ 'validation' => DataValidator::dataStoreId('department'), 'error' => ERRORS::INVALID_DEPARTMENT @@ -46,18 +43,20 @@ class EditDepartmentController extends Controller { } public function handler() { + $newname = Controller::request('name'); $departmentId = Controller::request('departmentId'); + $private = Controller::request('private'); $departmentInstance = Department::getDataStore($departmentId); - $departmentInstance->name = $newname ; - + $newname ? $departmentInstance->name = $newname : null; + $departmentInstance->private = $private ? 1 : 0; $departmentInstance->store(); Log::createLog('EDIT_DEPARTMENT', $departmentInstance->name); - + Response::respondSuccess(); } -} \ No newline at end of file +} diff --git a/server/controllers/system/get-settings.php b/server/controllers/system/get-settings.php index 5dcd636b..2d7fc2b7 100755 --- a/server/controllers/system/get-settings.php +++ b/server/controllers/system/get-settings.php @@ -50,7 +50,7 @@ class GetSettingsController extends Controller { 'smtp-host' => Setting::getSetting('smtp-host')->getValue(), 'smtp-user' => Setting::getSetting('smtp-user')->getValue(), 'registration' => Setting::getSetting('registration')->getValue(), - 'departments' => Department::getDepartmentNames(), + 'departments' => Department::getAllDepartmentNames(), 'supportedLanguages' => Language::getSupportedLanguages(), 'allowedLanguages' => Language::getAllowedLanguages(), 'session-prefix' => Setting::getSetting('session-prefix') @@ -66,7 +66,7 @@ class GetSettingsController extends Controller { 'max-size' => Setting::getSetting('max-size')->getValue(), 'title' => Setting::getSetting('title')->getValue(), 'registration' => Setting::getSetting('registration')->getValue(), - 'departments' => Department::getDepartmentNames(), + 'departments' => Controller::isStaffLogged() ? Department::getAllDepartmentNames() : Department::getPublicDepartmentNames(), 'supportedLanguages' => Language::getSupportedLanguages(), 'allowedLanguages' => Language::getAllowedLanguages(), 'user-system-enabled' => intval(Setting::getSetting('user-system-enabled')->getValue()), diff --git a/server/controllers/ticket/change-department.php b/server/controllers/ticket/change-department.php index 47021b06..68092c0f 100755 --- a/server/controllers/ticket/change-department.php +++ b/server/controllers/ticket/change-department.php @@ -52,6 +52,10 @@ class ChangeDepartmentController extends Controller { $department = Department::getDataStore($departmentId); $user = Controller::getLoggedUser(); + if(!$ticket->authorStaffId && $department->private){ + throw new Exception(ERRORS::NO_PERMISSION); + } + if($ticket->owner && $ticket->owner->id !== $user->id && $user->level == 1){ throw new Exception(ERRORS::NO_PERMISSION); } @@ -67,8 +71,8 @@ class ChangeDepartmentController extends Controller { $ticket->unread = !$ticket->isAuthor($user); $ticket->store(); - if(!$user->sharedDepartmentList->includesId($department->id)) { - $unAssignTicketController = new UnAssignStaffController(); + if($ticket->owner && !$ticket->owner->sharedDepartmentList->includesId($department->id)) { + $unAssignTicketController = new UnAssignStaffController($ticket->owner); $unAssignTicketController->validate(); $unAssignTicketController->handler(); } diff --git a/server/controllers/ticket/create.php b/server/controllers/ticket/create.php index 112f0391..709f2a9b 100755 --- a/server/controllers/ticket/create.php +++ b/server/controllers/ticket/create.php @@ -99,6 +99,9 @@ class CreateController extends Controller { $this->email = Controller::request('email'); $this->name = Controller::request('name'); + if(!Controller::isStaffLogged() && Department::getDataStore($this->departmentId)->private){ + throw new Exception(ERRORS::INVALID_DEPARTMENT); + } $this->storeTicket(); if(!Controller::isUserSystemEnabled()) { diff --git a/server/models/Department.php b/server/models/Department.php index d15a7e37..d856bb68 100755 --- a/server/models/Department.php +++ b/server/models/Department.php @@ -8,26 +8,28 @@ use RedBeanPHP\Facade as RedBean; * @apiParam {Number} id Id of the department. * @apiParam {String} name Name of the department. * @apiParam {[Staff](#api-Data_Structures-ObjectStaff)[]} owners List of owners of the department. + * @apiParam {Boolean} private Indicates if the departmetn is not shown to users. */ class Department extends DataStore { const TABLE = 'department'; - + public static function getProps() { return [ 'name', 'sharedTicketList', - 'owners' - ]; - } - - public function getDefaultProps() { - return [ - 'owners' => 0 + 'owners', + 'private' ]; } - public static function getDepartmentNames() { + public function getDefaultProps() { + return [ + 'owners' => 0 + ]; + } + + public static function getAllDepartmentNames() { $departmentsList = RedBean::findAll(Department::TABLE); $departmentsNameList = []; @@ -35,12 +37,32 @@ class Department extends DataStore { $departmentsNameList[] = [ 'id' => $department->id, 'name' => $department->name, - 'owners' => $department->owners + 'owners' => $department->owners, + 'private' => $department->private ]; } - + return $departmentsNameList; } + + public static function getPublicDepartmentNames() { + $departmentsList = RedBean::findAll(Department::TABLE); + $departmentsNameList = []; + + foreach($departmentsList as $department) { + if(!$department->private) { + $departmentsNameList[] = [ + 'id' => $department->id, + 'name' => $department->name, + 'owners' => $department->owners, + 'private' => $department->private + ]; + } + } + + return $departmentsNameList; + } + public function toArray() { return [ 'id' => $this->id, @@ -48,4 +70,4 @@ class Department extends DataStore { 'owners' => $this->owners ]; } -} \ No newline at end of file +} diff --git a/tests/Makefile b/tests/Makefile index b30f4e1c..1b0d3002 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -7,7 +7,7 @@ install: @bundle install run: export MYSQL_HOST=127.0.0.1 -run: export MYSQL_PORT=4040 +run: export MYSQL_PORT=3306 run: ./run-tests.sh From b4dc92b8f174a5e8dbbd9b2b19c9973a440a3990 Mon Sep 17 00:00:00 2001 From: Guillermo Date: Fri, 23 Nov 2018 19:44:10 -0300 Subject: [PATCH 2/7] features #340 --- client/src/app-components/ticket-viewer.js | 11 ++------ tests/staff/get-all.rb | 4 +-- tests/system/add-department.rb | 23 +++++++++++++-- tests/system/get-settings.rb | 2 +- tests/ticket/change-department.rb | 4 +-- tests/ticket/create.rb | 33 ++++++++++++++++++++++ tests/ticket/events.rb | 19 +++++-------- tests/user/get-users-test.rb | 2 +- 8 files changed, 69 insertions(+), 29 deletions(-) diff --git a/client/src/app-components/ticket-viewer.js b/client/src/app-components/ticket-viewer.js index 22ec5e38..0ccd705d 100644 --- a/client/src/app-components/ticket-viewer.js +++ b/client/src/app-components/ticket-viewer.js @@ -86,7 +86,7 @@ class TicketViewer extends React.Component { renderEditableHeaders() { const ticket = this.props.ticket; - const departments = SessionStore.getDepartments(); + const departments = (this.props.ticket.author.staff ? SessionStore.getDepartments() : this.getPublicDepartments() ); const priorities = { 'low': 0, @@ -302,14 +302,7 @@ class TicketViewer extends React.Component { }; } getPublicDepartments() { - var publicdepartments = Session.Store.getDepartments().map((department) => { - if(department.private*1){ - null; - }else { - department.name; - } - }); - return publicdepartments; + return _.filter(SessionStore.getDepartments(),d => !(d.private*1)); } onDepartmentDropdownChanged(event) { diff --git a/tests/staff/get-all.rb b/tests/staff/get-all.rb index 5f3d3267..d7651cf8 100644 --- a/tests/staff/get-all.rb +++ b/tests/staff/get-all.rb @@ -17,9 +17,9 @@ describe'/staff/get-all' do (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('Suggestions') + (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('Tech support') + (result['data'][0]['departments'][2]['name']).should.equal('Suggestions') (result['data'][0]['assignedTickets']).should.equal(6) (result['data'][0]['closedTickets']).should.equal(0) diff --git a/tests/system/add-department.rb b/tests/system/add-department.rb index a4613026..5674f962 100644 --- a/tests/system/add-department.rb +++ b/tests/system/add-department.rb @@ -13,7 +13,8 @@ describe'system/add-department' do row = $database.getRow('department', 4, 'id') - (row['name']).should.equal('new department') + (row['name']).should.equal('Tech support') + (row['private']).should.equal("0") lastLog = $database.getLastRow('log') (lastLog['type']).should.equal('ADD_DEPARTMENT') @@ -30,7 +31,25 @@ describe'system/add-department' do row = $database.getRow('department', 5, 'id') - (row['name']).should.equal('new department') + (row['name']).should.equal('new department') + (row['private']).should.equal("0") + + lastLog = $database.getLastRow('log') + (lastLog['type']).should.equal('ADD_DEPARTMENT') + end + + it 'should add a private department' do + result = request('/system/add-department', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + name: 'a private department', + private: 1 + }) + + (result['status']).should.equal('success') + + row = $database.getRow('department', 'a private department', 'name') + (row['private']).should.equal('1') lastLog = $database.getLastRow('log') (lastLog['type']).should.equal('ADD_DEPARTMENT') diff --git a/tests/system/get-settings.rb b/tests/system/get-settings.rb index a64f44bd..383d1207 100644 --- a/tests/system/get-settings.rb +++ b/tests/system/get-settings.rb @@ -17,4 +17,4 @@ describe '/system/get-settings' do (result['data']['allowedLanguages'][9]).should.equal('tr') (result['data']['supportedLanguages'][0]).should.equal('en') end -end \ No newline at end of file +end diff --git a/tests/ticket/change-department.rb b/tests/ticket/change-department.rb index f8c02c12..73b4f260 100644 --- a/tests/ticket/change-department.rb +++ b/tests/ticket/change-department.rb @@ -29,7 +29,7 @@ describe '/ticket/change-department' do result = request('/ticket/change-department', { ticketNumber: ticket['ticket_number'], - departmentId: 2, + departmentId: 3, csrf_userid: $csrf_userid, csrf_token: $csrf_token }) @@ -38,7 +38,7 @@ describe '/ticket/change-department' do ticket = $database.getRow('ticket', 1 , 'id') (ticket['unread']).should.equal('1') - (ticket['department_id']).should.equal('2') + (ticket['department_id']).should.equal('3') (ticket['owner_id']).should.equal('1') lastLog = $database.getLastRow('log') diff --git a/tests/ticket/create.rb b/tests/ticket/create.rb index 8d090586..9632c86b 100644 --- a/tests/ticket/create.rb +++ b/tests/ticket/create.rb @@ -78,8 +78,41 @@ describe '/ticket/create' do (result['message']).should.equal('INVALID_DEPARTMENT') end + it 'should fail if an user tries to create a ticket with a private department' do + request('/user/logout') + Scripts.login('staff@opensupports.com', 'staff', true) + + result = request('/system/add-department', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + name: 'useless private deapartment', + private: 1 + }) + + row = $database.getRow('department', 'useless private deapartment', 'name') + + request('/user/logout') + Scripts.createUser('user@os4.com', 'loginpass') + Scripts.login('user@os4.com', 'loginpass') + + result = request('/ticket/create', { + title: 'Winter is here', + content: 'The king in the north', + departmentId: row['id'], + language: 'en', + csrf_userid: $csrf_userid, + csrf_token: $csrf_token + }) + + (result['status']).should.equal('fail') + (result['message']).should.equal('INVALID_DEPARTMENT') + + request('/user/logout') + end it 'should create ticket if pass data is valid' do + Scripts.login('creator@os4.com','creator') + result = request('/ticket/create', { title: 'Winter is coming', content: 'The north remembers', diff --git a/tests/ticket/events.rb b/tests/ticket/events.rb index be6b71d0..cf7bd25a 100644 --- a/tests/ticket/events.rb +++ b/tests/ticket/events.rb @@ -97,22 +97,17 @@ describe 'Ticket Events' do (result['data']['events'][4]['author']['name']).should.equal('Emilia Clarke') (result['data']['events'][4]['author']['staff']).should.equal(true) - (result['data']['events'][5]['type']).should.equal('DEPARTMENT_CHANGED') - (result['data']['events'][5]['content']).should.equal('Suggestions') + (result['data']['events'][5]['type']).should.equal('CLOSE') (result['data']['events'][5]['author']['name']).should.equal('Emilia Clarke') (result['data']['events'][5]['author']['staff']).should.equal(true) - (result['data']['events'][6]['type']).should.equal('CLOSE') - (result['data']['events'][6]['author']['name']).should.equal('Emilia Clarke') - (result['data']['events'][6]['author']['staff']).should.equal(true) + (result['data']['events'][6]['type']).should.equal('RE_OPEN') + (result['data']['events'][6]['author']['name']).should.equal('Tyrion Lannister') + (result['data']['events'][6]['author']['staff']).should.equal(false) - (result['data']['events'][7]['type']).should.equal('RE_OPEN') + (result['data']['events'][7]['type']).should.equal('COMMENT') + (result['data']['events'][7]['content']).should.equal('This is a comment made by a regular user') (result['data']['events'][7]['author']['name']).should.equal('Tyrion Lannister') (result['data']['events'][7]['author']['staff']).should.equal(false) - - (result['data']['events'][8]['type']).should.equal('COMMENT') - (result['data']['events'][8]['content']).should.equal('This is a comment made by a regular user') - (result['data']['events'][8]['author']['name']).should.equal('Tyrion Lannister') - (result['data']['events'][8]['author']['staff']).should.equal(false) end -end \ No newline at end of file +end diff --git a/tests/user/get-users-test.rb b/tests/user/get-users-test.rb index b20bbec1..cf195cd8 100644 --- a/tests/user/get-users-test.rb +++ b/tests/user/get-users-test.rb @@ -36,7 +36,7 @@ describe '/user/get-users' do }) (result['status']).should.equal('success') - (result['data']['users'].size).should.equal(6) + (result['data']['users'].size).should.equal(7) end it 'should get users with order by tickets and asc' do From 6596e29d9cd9d2b47b83b48a5a6460734c99e5e6 Mon Sep 17 00:00:00 2001 From: Guillermo Date: Fri, 23 Nov 2018 22:44:40 -0300 Subject: [PATCH 3/7] fix test --- .../__tests__/ticket-list-test.js | 22 +++++++++---------- client/src/app-components/ticket-list.js | 5 ++--- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/client/src/app-components/__tests__/ticket-list-test.js b/client/src/app-components/__tests__/ticket-list-test.js index 8e591a48..333229a7 100644 --- a/client/src/app-components/__tests__/ticket-list-test.js +++ b/client/src/app-components/__tests__/ticket-list-test.js @@ -3,7 +3,7 @@ const TicketInfo = ReactMock(); const Table = ReactMock(); const Button = ReactMock(); const Tooltip = ReactMock(); -const Dropdown = ReactMock(); +const DepartmentDropdown = ReactMock(); const i18n = stub().returnsArg(0); const TicketList = requireUnit('app-components/ticket-list', { @@ -11,7 +11,7 @@ const TicketList = requireUnit('app-components/ticket-list', { 'core-components/table': Table, 'core-components/button': Button, 'core-components/tooltip': Tooltip, - 'core-components/drop-down': Dropdown, + 'app-components/department-dropdown': DepartmentDropdown, 'lib-app/i18n': i18n }); @@ -54,7 +54,7 @@ describe('TicketList component', function () { ); table = TestUtils.scryRenderedComponentsWithType(ticketList, Table); - dropdown = TestUtils.scryRenderedComponentsWithType(ticketList, Dropdown); + dropdown = TestUtils.scryRenderedComponentsWithType(ticketList, DepartmentDropdown); } it('should pass correct props to Table', function () { @@ -84,12 +84,12 @@ describe('TicketList component', function () { } ]); }); - + it('should pass loading to Table', function () { renderTicketList({loading: true}); expect(table[0].props.loading).to.equal(true); }); - + it('should pass correct compare function to Table', function () { let minCompare = table[0].props.comp; @@ -114,7 +114,7 @@ describe('TicketList component', function () { row2.date = '20160401'; expect(minCompare(row1, row2)).to.equal(-1); }); - + describe('when using secondary type', function () { beforeEach(function () { renderTicketList({ @@ -162,10 +162,10 @@ describe('TicketList component', function () { }); it('should pass correct props to dropdown', function () { - expect(dropdown[0].props.items).to.deep.equal([ - {content: i18n('ALL_DEPARTMENTS')}, - {content: 'Sales Support'}, - {content: 'Tech Help'} + expect(dropdown[0].props.departments).to.deep.equal([ + {name: i18n('ALL_DEPARTMENTS')}, + {name: 'Sales Support', id: 1}, + {name: 'Tech Help', id: 2} ]); expect(dropdown[0].props.size).to.equal('medium'); }); @@ -185,4 +185,4 @@ describe('TicketList component', function () { expect(table[0].props.rows.length).to.equal(10); }); }); -}); \ No newline at end of file +}); diff --git a/client/src/app-components/ticket-list.js b/client/src/app-components/ticket-list.js index 07513b0e..10caf79b 100644 --- a/client/src/app-components/ticket-list.js +++ b/client/src/app-components/ticket-list.js @@ -45,9 +45,8 @@ class TicketList extends React.Component { render() { return (
-
- {(this.props.type === 'secondary' && this.props.showDepartmentDropdown) ? this.renderDepartments - () : null} +
+ {(this.props.type === 'secondary' && this.props.showDepartmentDropdown) ? this.renderDepartmentsDropDown() : null} {this.props.onClosedTicketsShownChange ? this.renderFilterCheckbox() : null}
From 1bc30240bd662830a47006d5c2455db5d7703765 Mon Sep 17 00:00:00 2001 From: Guillermo Date: Mon, 26 Nov 2018 02:43:37 -0300 Subject: [PATCH 4/7] fix test --- tests/ticket/events.rb | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tests/ticket/events.rb b/tests/ticket/events.rb index cf7bd25a..4688bf3d 100644 --- a/tests/ticket/events.rb +++ b/tests/ticket/events.rb @@ -44,7 +44,7 @@ describe 'Ticket Events' do csrf_token: $csrf_token }) request('/ticket/change-department', { - departmentId: 2, + departmentId: 3, ticketNumber: ticketNumber, csrf_userid: $csrf_userid, csrf_token: $csrf_token @@ -97,17 +97,22 @@ describe 'Ticket Events' do (result['data']['events'][4]['author']['name']).should.equal('Emilia Clarke') (result['data']['events'][4]['author']['staff']).should.equal(true) - (result['data']['events'][5]['type']).should.equal('CLOSE') + (result['data']['events'][5]['type']).should.equal('DEPARTMENT_CHANGED') + (result['data']['events'][5]['content']).should.equal('Suggestions') (result['data']['events'][5]['author']['name']).should.equal('Emilia Clarke') (result['data']['events'][5]['author']['staff']).should.equal(true) - (result['data']['events'][6]['type']).should.equal('RE_OPEN') - (result['data']['events'][6]['author']['name']).should.equal('Tyrion Lannister') - (result['data']['events'][6]['author']['staff']).should.equal(false) + (result['data']['events'][6]['type']).should.equal('CLOSE') + (result['data']['events'][6]['author']['name']).should.equal('Emilia Clarke') + (result['data']['events'][6]['author']['staff']).should.equal(true) - (result['data']['events'][7]['type']).should.equal('COMMENT') - (result['data']['events'][7]['content']).should.equal('This is a comment made by a regular user') + (result['data']['events'][7]['type']).should.equal('RE_OPEN') (result['data']['events'][7]['author']['name']).should.equal('Tyrion Lannister') (result['data']['events'][7]['author']['staff']).should.equal(false) + + (result['data']['events'][8]['type']).should.equal('COMMENT') + (result['data']['events'][8]['content']).should.equal('This is a comment made by a regular user') + (result['data']['events'][8]['author']['name']).should.equal('Tyrion Lannister') + (result['data']['events'][8]['author']['staff']).should.equal(false) end end From d2b6f1cc30b2e0391399ee2364e4900ad90df696 Mon Sep 17 00:00:00 2001 From: Guillermo Date: Mon, 26 Nov 2018 15:09:34 -0300 Subject: [PATCH 5/7] fix tst --- server/controllers/article/edit-topic.php | 2 +- server/controllers/article/get-all.php | 6 ++- tests/article/article.rb | 50 +++++++++++++++++++++-- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/server/controllers/article/edit-topic.php b/server/controllers/article/edit-topic.php index 0a0d75ab..4e4adf6b 100755 --- a/server/controllers/article/edit-topic.php +++ b/server/controllers/article/edit-topic.php @@ -57,7 +57,7 @@ class EditTopicController extends Controller { if(Controller::request('icon')) { $topic->icon = Controller::request('icon'); } - if(Controller::request('private') || Controller::request('private') == 0) { + if (Controller::request('private') !== null) { $topic->private = Controller::request('private'); } diff --git a/server/controllers/article/get-all.php b/server/controllers/article/get-all.php index 54aa4214..84bf01e7 100755 --- a/server/controllers/article/get-all.php +++ b/server/controllers/article/get-all.php @@ -35,7 +35,11 @@ class GetAllArticlesController extends Controller { $topicsArray = []; foreach($topics as $topic) { - Controller::isStaffLogged() ? $topicsArray[] = $topic->toArray() : ($topic->private*1 ? null : $topicsArray[] = $topic->toArray()) ; + if (Controller::isStaffLogged()) { + $topicsArray[] = $topic->toArray(); + } else if (!$topic->private) { + $topicsArray[] = $topic->toArray(); + } } Response::respondSuccess($topicsArray); diff --git a/tests/article/article.rb b/tests/article/article.rb index 2b2d3389..c6ad9d08 100644 --- a/tests/article/article.rb +++ b/tests/article/article.rb @@ -6,10 +6,26 @@ describe 'Article path' do icon: 'cogs', iconColor: 'red', csrf_userid: $csrf_userid, - csrf_token: $csrf_token + csrf_token: $csrf_token, + private: 0 }) @topic_id = topic['data']['topicId'] + it 'should create a private topic' do + result = request('/article/add-topic', { + name: 'Private Topic', + icon: 'cogs', + iconColor: 'green', + csrf_userid: $csrf_userid, + csrf_token: $csrf_token, + private: 1 + }) + row = $database.getRow('topic', 'Private Topic', 'name') + + result['status'].should.equal('success') + (row['private']).should.equal('1') + end + it 'should create article' do result = request('/article/add', { title: 'Some article', @@ -108,13 +124,39 @@ describe 'Article path' do (result['data'][0]['name']).should.equal('Server management') (result['data'][0]['icon']).should.equal('cogs') (result['data'][0]['iconColor']).should.equal('red') - (result['data'][1]['name']).should.equal('Software installation') - (result['data'][1]['icon']).should.equal('photo') - (result['data'][1]['iconColor']).should.equal('blue') + (result['data'][0]['private']).should.equal('0') + (result['data'][1]['name']).should.equal('Private Topic') + (result['data'][1]['icon']).should.equal('cogs') + (result['data'][1]['iconColor']).should.equal('green') + (result['data'][1]['private']).should.equal('1') + (result['data'][2]['name']).should.equal('Software installation') + (result['data'][2]['icon']).should.equal('photo') + (result['data'][2]['iconColor']).should.equal('blue') + (result['data'][2]['private']).should.equal('0') (result['data'][0]['articles'][0]['title']).should.equal('Some article') (result['data'][0]['articles'][0]['content']).should.equal('This is an article about server management.') (result['data'][0]['articles'][0]['position']).should.equal('1') end + it 'should retrieve public departments' do + request('/user/logout') + Scripts.login('tyrion@opensupports.com', 'tyrionl') + + result = request('/article/get-all', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token + }) + (result['status']).should.equal('success') + + (result['data'][0]['name']).should.equal('Server management') + (result['data'][0]['icon']).should.equal('cogs') + (result['data'][0]['iconColor']).should.equal('red') + (result['data'][0]['private']).should.equal('0') + (result['data'][1]['name']).should.equal('Software installation') + (result['data'][1]['icon']).should.equal('photo') + (result['data'][1]['iconColor']).should.equal('blue') + (result['data'][1]['private']).should.equal('0') + + end end From 80934ff3f85e891e69b7114c6b45483e8ed53397 Mon Sep 17 00:00:00 2001 From: Guillermo Giuliana Date: Mon, 26 Nov 2018 17:08:56 -0300 Subject: [PATCH 6/7] Delete edit-topic.php --- server/controllers/article/edit-topic.php | 67 ----------------------- 1 file changed, 67 deletions(-) delete mode 100755 server/controllers/article/edit-topic.php diff --git a/server/controllers/article/edit-topic.php b/server/controllers/article/edit-topic.php deleted file mode 100755 index 4e4adf6b..00000000 --- a/server/controllers/article/edit-topic.php +++ /dev/null @@ -1,67 +0,0 @@ - 'staff_2', - 'requestData' => [ - 'topicId' => [ - 'validation' => DataValidator::dataStoreId('topic'), - 'error' => ERRORS::INVALID_TOPIC - ] - ] - ]; - } - - public function handler() { - $topic = Topic::getDataStore(Controller::request('topicId')); - - if(Controller::request('name')) { - $topic->name = Controller::request('name'); - } - - if(Controller::request('iconColor')) { - $topic->iconColor = Controller::request('iconColor'); - } - - if(Controller::request('icon')) { - $topic->icon = Controller::request('icon'); - } - if (Controller::request('private') !== null) { - $topic->private = Controller::request('private'); - } - - $topic->store(); - Response::respondSuccess(); - } -} From aa795c30998fb18e768bf74d8a39910626f4fd20 Mon Sep 17 00:00:00 2001 From: Guillermo Date: Mon, 26 Nov 2018 22:47:39 -0300 Subject: [PATCH 7/7] Revert "Delete edit-topic.php" This reverts commit 80934ff3f85e891e69b7114c6b45483e8ed53397. --- server/controllers/article/edit-topic.php | 67 +++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100755 server/controllers/article/edit-topic.php diff --git a/server/controllers/article/edit-topic.php b/server/controllers/article/edit-topic.php new file mode 100755 index 00000000..4e4adf6b --- /dev/null +++ b/server/controllers/article/edit-topic.php @@ -0,0 +1,67 @@ + 'staff_2', + 'requestData' => [ + 'topicId' => [ + 'validation' => DataValidator::dataStoreId('topic'), + 'error' => ERRORS::INVALID_TOPIC + ] + ] + ]; + } + + public function handler() { + $topic = Topic::getDataStore(Controller::request('topicId')); + + if(Controller::request('name')) { + $topic->name = Controller::request('name'); + } + + if(Controller::request('iconColor')) { + $topic->iconColor = Controller::request('iconColor'); + } + + if(Controller::request('icon')) { + $topic->icon = Controller::request('icon'); + } + if (Controller::request('private') !== null) { + $topic->private = Controller::request('private'); + } + + $topic->store(); + Response::respondSuccess(); + } +}