Ivan - Add articles paths [skip ci]

This commit is contained in:
ivan 2016-11-22 22:27:05 -03:00
parent d227b3f34d
commit 94fd359098
18 changed files with 502 additions and 7 deletions

View File

@ -0,0 +1,21 @@
<?php
include 'article/add-topic.php';
include 'article/edit-topic.php';
include 'article/delete-topic.php';
include 'article/add.php';
include 'article/edit.php';
include 'article/delete.php';
include 'article/get-all.php';
$articleControllers = new ControllerGroup();
$articleControllers->setGroupPath('/article');
$articleControllers->addController(new AddTopicController);
$articleControllers->addController(new EditTopicController);
$articleControllers->addController(new DeleteTopicController);
$articleControllers->addController(new AddArticleController);
$articleControllers->addController(new EditArticleController);
$articleControllers->addController(new DeleteArticleController);
$articleControllers->addController(new GetAllArticlesController);
$articleControllers->finalize();

View File

@ -0,0 +1,32 @@
<?php
use Respect\Validation\Validator as DataValidator;
DataValidator::with('CustomValidations', true);
class AddTopicController extends Controller {
const PATH = '/add-topic';
public function validations() {
return [
'permission' => 'staff_2',
'requestData' => [
'name' => [
'validation' => DataValidator::length(3, 40),
'error' => ERRORS::INVALID_NAME
]
]
];
}
public function handler() {
$topic = new Topic();
$topic->setProperties([
'name' => Controller::request('name'),
'icon' => Controller::request('icon'),
'iconColor' => Controller::request('iconColor')
]);
Response::respondSuccess([
'topicId' => $topic->store()
]);
}
}

View File

@ -0,0 +1,45 @@
<?php
use Respect\Validation\Validator as DataValidator;
DataValidator::with('CustomValidations', true);
class AddArticleController extends Controller {
const PATH = '/add';
public function validations() {
return [
'permission' => 'staff_2',
'requestData' => [
'title' => [
'validation' => DataValidator::length(3, 40),
'error' => ERRORS::INVALID_NAME
],
'content' => [
'validation' => DataValidator::length(10),
'error' => ERRORS::INVALID_CONTENT
],
'topicId' => [
'validation' => DataValidator::dataStoreId('topic'),
'error' => ERRORS::INVALID_TOPIC
]
]
];
}
public function handler() {
$article = new Article();
$article->setProperties([
'title' => Controller::request('title'),
'content' => Controller::request('content'),
'lastEdited' => Date::getCurrentDate(),
'position' => Controller::request('position') || 1
]);
$topic = Topic::getDataStore(Controller::request('topicId'));
$topic->ownArticleList->add($article);
$topic->store();
Response::respondSuccess([
'articleId' => $article->store()
]);
}
}

View File

@ -0,0 +1,26 @@
<?php
use Respect\Validation\Validator as DataValidator;
DataValidator::with('CustomValidations', true);
class DeleteTopicController extends Controller {
const PATH = '/delete-topic';
public function validations() {
return [
'permission' => 'staff_2',
'requestData' => [
'topicId' => [
'validation' => DataValidator::dataStoreId('topic'),
'error' => ERRORS::INVALID_TOPIC
]
]
];
}
public function handler() {
$topic = Topic::getDataStore(Controller::request('topicId'));
$topic->delete();
Response::respondSuccess();
}
}

View File

@ -0,0 +1,26 @@
<?php
use Respect\Validation\Validator as DataValidator;
DataValidator::with('CustomValidations', true);
class DeleteArticleController extends Controller {
const PATH = '/delete';
public function validations() {
return [
'permission' => 'staff_2',
'requestData' => [
'articleId' => [
'validation' => DataValidator::dataStoreId('article'),
'error' => ERRORS::INVALID_TOPIC
]
]
];
}
public function handler() {
$article = Article::getDataStore(Controller::request('articleId'));
$article->delete();
Response::respondSuccess();
}
}

View File

@ -0,0 +1,38 @@
<?php
use Respect\Validation\Validator as DataValidator;
DataValidator::with('CustomValidations', true);
class EditTopicController extends Controller {
const PATH = '/edit-topic';
public function validations() {
return [
'permission' => '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');
}
$topic->store();
Response::respondSuccess();
}
}

View File

@ -0,0 +1,56 @@
<?php
use Respect\Validation\Validator as DataValidator;
DataValidator::with('CustomValidations', true);
class EditArticleController extends Controller {
const PATH = '/edit';
public function validations() {
return [
'permission' => 'staff_2',
'requestData' => [
'articleId' => [
'validation' => DataValidator::dataStoreId('article'),
'error' => ERRORS::INVALID_TOPIC
]
]
];
}
public function handler() {
$article = Article::getDataStore(Controller::request('articleId'));
if (Controller::request('topicId')) {
$currentArticleTopic = $article->topic;
$newArticleTopic = Topic::getDataStore(Controller::request('topicId'));
if (!$newArticleTopic->isNull() /*&& $currentArticleTopic->ownArticleList->remove($article)*/) {
/*$newArticleTopic->ownArticleList->add($article);
$currentArticleTopic->store();
$newArticleTopic->store();*/
$article->topic = $newArticleTopic;
} else {
Response::respondError(ERRORS::INVALID_TOPIC);
return;
}
}
if(Controller::request('content')) {
$article->content = Controller::request('content');
}
if(Controller::request('title')) {
$article->title = Controller::request('title');
}
if(Controller::request('position')) {
$article->position = Controller::request('position');
}
$article->lastEdited = Date::getCurrentDate();
$article->store();
Response::respondSuccess();
}
}

View File

@ -0,0 +1,25 @@
<?php
use Respect\Validation\Validator as DataValidator;
DataValidator::with('CustomValidations', true);
class GetAllArticlesController extends Controller {
const PATH = '/get-all';
public function validations() {
return [
'permission' => 'user',
'requestData' => []
];
}
public function handler() {
$topics = Topic::getAll();
$topicsArray = [];
foreach($topics as $topic) {
$topicsArray[] = $topic->toArray();
}
Response::respondSuccess($topicsArray);
}
}

View File

@ -19,7 +19,7 @@ class DeleteCustomResponseController extends Controller {
public function handler() {
$customResponse = CustomResponse::getDataStore(Controller::request('id'));
$customResponse->trash();
$customResponse->delete();
Response::respondSuccess();
}

View File

@ -21,4 +21,5 @@ class ERRORS {
const INVALID_PRIORITY = 'INVALID_PRIORITY';
const INVALID_PAGE = 'INVALID_PAGE';
const INVALID_QUERY = 'INVALID_QUERY';
const INVALID_TOPIC = 'INVALID_TOPIC';
}

View File

@ -25,7 +25,12 @@ class DataStoreList implements IteratorAggregate {
public function remove(DataStore $dataStore) {
$dataStoreIndexInList = $this->getIndexInListOf($dataStore);
unset($this->list[$dataStoreIndexInList]);
if ($dataStoreIndexInList == -1) {
return false;
} else {
unset($this->list[$dataStoreIndexInList]);
return true;
}
}
public function toBeanList() {

View File

@ -31,6 +31,12 @@ class DataStoreId extends AbstractRule {
case 'customresponse':
$dataStore = \CustomResponse::getDataStore($dataStoreId);
break;
case 'topic':
$dataStore = \Topic::getDataStore($dataStoreId);
break;
case 'article':
$dataStore = \Article::getDataStore($dataStoreId);
break;
}
return !$dataStore->isNull();
@ -41,7 +47,9 @@ class DataStoreId extends AbstractRule {
'user',
'ticket',
'department',
'customresponse'
'customresponse',
'topic',
'article'
]);
}
}

View File

@ -8,7 +8,18 @@ class Article extends DataStore {
'title',
'content',
'lastEdited',
'topic',
'position'
];
}
public function toArray() {
return [
'id' => $this->id,
'title' => $this->title,
'content' => $this->content,
'lastEdited' => $this->lastEdited,
'position' => $this->position
];
}
}

View File

@ -126,10 +126,6 @@ abstract class DataStore {
return RedBean::store($this->getBeanInstance());
}
public function trash() {
RedBean::trash($this->getBeanInstance());
}
public function delete() {
RedBean::trash($this->getBeanInstance());
unset($this);

View File

@ -11,4 +11,19 @@ class Topic extends DataStore {
'ownArticleList'
];
}
public function toArray() {
$articlesArray = [];
foreach($this->ownArticleList as $article) {
$articlesArray[] = $article->toArray();
}
return [
'name' => $this->name,
'icon' => $this->icon,
'iconColor' => $this->iconColor,
'articles' => $articlesArray
];
}
}

107
tests/article/article.rb Normal file
View File

@ -0,0 +1,107 @@
describe 'Article path' do
request('/user/logout')
Scripts.login($staff[:email], $staff[:password], true)
topic = request('/article/add-topic', {
name: 'Server management',
icon: 'cogs',
iconColor: 'red',
csrf_userid: $csrf_userid,
csrf_token: $csrf_token
})
@topic_id = topic['data']['topicId']
it 'should create article' do
result = request('/article/add', {
title: 'Some article',
content: 'This is an article about server management.',
topicId: @topic_id,
position: 1,
csrf_userid: $csrf_userid,
csrf_token: $csrf_token
})
(result['status']).should.equal('success')
@article_id = result['data']['articleId']
article = $database.getRow('article', @article_id)
(article['title']).should.equal('Some article')
(article['content']).should.equal('This is an article about server management.')
(article['topic_id']).should.equal(@topic_id.to_s)
(article['position']).should.equal('1')
end
it 'should edit article' do
result = request('/article/edit', {
articleId: @article_id,
content: 'This is an article about server management2.',
csrf_userid: $csrf_userid,
csrf_token: $csrf_token
})
(result['status']).should.equal('success')
article = $database.getRow('article', @article_id)
(article['title']).should.equal('Some article')
(article['content']).should.equal('This is an article about server management2.')
(article['topic_id']).should.equal(@topic_id.to_s)
(article['position']).should.equal('1')
end
it 'should edit article topic' do
request('/article/add-topic', {
name: 'Software installation',
icon: 'photo',
iconColor: 'blue',
csrf_userid: $csrf_userid,
csrf_token: $csrf_token
})
result = request('/article/edit', {
articleId: @article_id,
topicId: @topic_id+1,
csrf_userid: $csrf_userid,
csrf_token: $csrf_token
})
(result['status']).should.equal('success')
article = $database.getRow('article', @article_id)
(article['title']).should.equal('Some article')
(article['content']).should.equal('This is an article about server management2.')
(article['topic_id']).should.equal((@topic_id+1).to_s)
(article['position']).should.equal('1')
end
it 'should delete article' do
result = request('/article/delete', {
articleId: @article_id,
csrf_userid: $csrf_userid,
csrf_token: $csrf_token
})
(result['status']).should.equal('success')
end
it 'should retrieve all articles' do
request('/article/add', {
title: 'Some article',
content: 'This is an article about server management.',
topicId: @topic_id,
position: 1,
csrf_userid: $csrf_userid,
csrf_token: $csrf_token
})
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'][1]['name']).should.equal('Software installation')
(result['data'][1]['icon']).should.equal('photo')
(result['data'][1]['iconColor']).should.equal('blue')
(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
end

81
tests/article/topic.rb Normal file
View File

@ -0,0 +1,81 @@
describe 'Topic paths' do
request('/user/logout')
Scripts.login($staff[:email], $staff[:password], true)
it 'should add topic correctly' do
result = request('/article/add-topic', {
name: 'Server management',
icon: 'cogs',
iconColor: 'red',
csrf_userid: $csrf_userid,
csrf_token: $csrf_token
})
(result['status']).should.equal('success')
topic = $database.getRow('topic', result['data']['topicId'])
(topic['name']).should.equal('Server management')
(topic['icon_color']).should.equal('red')
(topic['icon']).should.equal('cogs')
end
it 'should edit topic correctly' do
result = request('/article/edit-topic', {
topicId: 1,
name: 'Installation issues',
iconColor: 'blue',
csrf_userid: $csrf_userid,
csrf_token: $csrf_token
})
(result['status']).should.equal('success')
topic = $database.getRow('topic', 1)
(topic['name']).should.equal('Installation issues')
(topic['icon_color']).should.equal('blue')
(topic['icon']).should.equal('cogs')
end
it 'should delete topic correctly' do
result = request('/article/delete-topic', {
topicId: 1,
csrf_userid: $csrf_userid,
csrf_token: $csrf_token
})
(result['status']).should.equal('success')
end
it 'should deny permission if it is not logged as staff' do
request('/user/logout')
Scripts.login('tyrion@opensupports.com', 'tyrionl')
result = request('/article/add-topic', {
name: 'Server management',
icon: 'cogs',
iconColor: 'red',
csrf_userid: $csrf_userid,
csrf_token: $csrf_token
})
(result['status']).should.equal('fail')
(result['message']).should.equal('NO_PERMISSION')
result = request('/article/edit-topic', {
topicId: 1,
name: 'Installation issues',
iconColor: 'blue',
csrf_userid: $csrf_userid,
csrf_token: $csrf_token
})
(result['status']).should.equal('fail')
(result['message']).should.equal('NO_PERMISSION')
result = request('/article/delete-topic', {
topicId: 1,
csrf_userid: $csrf_userid,
csrf_token: $csrf_token
})
(result['status']).should.equal('fail')
(result['message']).should.equal('NO_PERMISSION')
end
end

View File

@ -33,5 +33,7 @@ require './ticket/change-priority.rb'
require './staff/get-new-tickets.rb'
require './staff/get-all-tickets.rb'
require './ticket/events.rb'
require './article/topic.rb'
require './article/article.rb'