From d227b3f34d6c98867036804f1fa94f23dc381d7a Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 21 Nov 2016 16:55:05 -0300 Subject: [PATCH 1/2] Ivan - Create article and topic datastore [skip ci] --- server/models/Article.php | 14 ++++++++++++++ server/models/Topic.php | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 server/models/Article.php create mode 100644 server/models/Topic.php diff --git a/server/models/Article.php b/server/models/Article.php new file mode 100644 index 00000000..27ce9b80 --- /dev/null +++ b/server/models/Article.php @@ -0,0 +1,14 @@ + Date: Tue, 22 Nov 2016 22:27:05 -0300 Subject: [PATCH 2/2] Ivan - Add articles paths [skip ci] --- server/controllers/article.php | 21 ++++ server/controllers/article/add-topic.php | 32 ++++++ server/controllers/article/add.php | 45 ++++++++ server/controllers/article/delete-topic.php | 26 +++++ server/controllers/article/delete.php | 26 +++++ server/controllers/article/edit-topic.php | 38 +++++++ server/controllers/article/edit.php | 56 +++++++++ server/controllers/article/get-all.php | 25 ++++ .../ticket/delete-custom-response.php | 2 +- server/data/ERRORS.php | 1 + server/libs/DataStoreList.php | 7 +- server/libs/validations/dataStoreId.php | 10 +- server/models/Article.php | 11 ++ server/models/DataStore.php | 4 - server/models/Topic.php | 15 +++ tests/article/article.rb | 107 ++++++++++++++++++ tests/article/topic.rb | 81 +++++++++++++ tests/init.rb | 2 + 18 files changed, 502 insertions(+), 7 deletions(-) create mode 100644 server/controllers/article.php create mode 100644 server/controllers/article/add-topic.php create mode 100644 server/controllers/article/add.php create mode 100644 server/controllers/article/delete-topic.php create mode 100644 server/controllers/article/delete.php create mode 100644 server/controllers/article/edit-topic.php create mode 100644 server/controllers/article/edit.php create mode 100644 server/controllers/article/get-all.php create mode 100644 tests/article/article.rb create mode 100644 tests/article/topic.rb diff --git a/server/controllers/article.php b/server/controllers/article.php new file mode 100644 index 00000000..e2079885 --- /dev/null +++ b/server/controllers/article.php @@ -0,0 +1,21 @@ +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(); \ No newline at end of file diff --git a/server/controllers/article/add-topic.php b/server/controllers/article/add-topic.php new file mode 100644 index 00000000..a13f7250 --- /dev/null +++ b/server/controllers/article/add-topic.php @@ -0,0 +1,32 @@ + '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() + ]); + } +} \ No newline at end of file diff --git a/server/controllers/article/add.php b/server/controllers/article/add.php new file mode 100644 index 00000000..f9701b32 --- /dev/null +++ b/server/controllers/article/add.php @@ -0,0 +1,45 @@ + '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() + ]); + } +} \ No newline at end of file diff --git a/server/controllers/article/delete-topic.php b/server/controllers/article/delete-topic.php new file mode 100644 index 00000000..0796bdf6 --- /dev/null +++ b/server/controllers/article/delete-topic.php @@ -0,0 +1,26 @@ + '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(); + } +} \ No newline at end of file diff --git a/server/controllers/article/delete.php b/server/controllers/article/delete.php new file mode 100644 index 00000000..43025631 --- /dev/null +++ b/server/controllers/article/delete.php @@ -0,0 +1,26 @@ + '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(); + } +} \ No newline at end of file diff --git a/server/controllers/article/edit-topic.php b/server/controllers/article/edit-topic.php new file mode 100644 index 00000000..c06fef30 --- /dev/null +++ b/server/controllers/article/edit-topic.php @@ -0,0 +1,38 @@ + '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(); + } +} \ No newline at end of file diff --git a/server/controllers/article/edit.php b/server/controllers/article/edit.php new file mode 100644 index 00000000..0b7729c4 --- /dev/null +++ b/server/controllers/article/edit.php @@ -0,0 +1,56 @@ + '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(); + } +} \ No newline at end of file diff --git a/server/controllers/article/get-all.php b/server/controllers/article/get-all.php new file mode 100644 index 00000000..9d90e152 --- /dev/null +++ b/server/controllers/article/get-all.php @@ -0,0 +1,25 @@ + 'user', + 'requestData' => [] + ]; + } + + public function handler() { + $topics = Topic::getAll(); + $topicsArray = []; + + foreach($topics as $topic) { + $topicsArray[] = $topic->toArray(); + } + + Response::respondSuccess($topicsArray); + } +} \ No newline at end of file diff --git a/server/controllers/ticket/delete-custom-response.php b/server/controllers/ticket/delete-custom-response.php index 087c3b4d..87608117 100644 --- a/server/controllers/ticket/delete-custom-response.php +++ b/server/controllers/ticket/delete-custom-response.php @@ -19,7 +19,7 @@ class DeleteCustomResponseController extends Controller { public function handler() { $customResponse = CustomResponse::getDataStore(Controller::request('id')); - $customResponse->trash(); + $customResponse->delete(); Response::respondSuccess(); } diff --git a/server/data/ERRORS.php b/server/data/ERRORS.php index 90f3b0d5..ea579d71 100644 --- a/server/data/ERRORS.php +++ b/server/data/ERRORS.php @@ -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'; } diff --git a/server/libs/DataStoreList.php b/server/libs/DataStoreList.php index ad209098..9305e094 100644 --- a/server/libs/DataStoreList.php +++ b/server/libs/DataStoreList.php @@ -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() { diff --git a/server/libs/validations/dataStoreId.php b/server/libs/validations/dataStoreId.php index 182d6774..a510cb55 100644 --- a/server/libs/validations/dataStoreId.php +++ b/server/libs/validations/dataStoreId.php @@ -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' ]); } } \ No newline at end of file diff --git a/server/models/Article.php b/server/models/Article.php index 27ce9b80..1168e258 100644 --- a/server/models/Article.php +++ b/server/models/Article.php @@ -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 + ]; + } } \ No newline at end of file diff --git a/server/models/DataStore.php b/server/models/DataStore.php index d73abfcd..dbcd93ac 100644 --- a/server/models/DataStore.php +++ b/server/models/DataStore.php @@ -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); diff --git a/server/models/Topic.php b/server/models/Topic.php index 5b556543..4c9dce86 100644 --- a/server/models/Topic.php +++ b/server/models/Topic.php @@ -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 + ]; + } } \ No newline at end of file diff --git a/tests/article/article.rb b/tests/article/article.rb new file mode 100644 index 00000000..606fc11f --- /dev/null +++ b/tests/article/article.rb @@ -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 \ No newline at end of file diff --git a/tests/article/topic.rb b/tests/article/topic.rb new file mode 100644 index 00000000..9da373c1 --- /dev/null +++ b/tests/article/topic.rb @@ -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 \ No newline at end of file diff --git a/tests/init.rb b/tests/init.rb index 82433322..0614319e 100644 --- a/tests/init.rb +++ b/tests/init.rb @@ -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'