/ */ class Comment_Test_IndexControllerTest extends ModuleControllerTest { protected $_commentModule; /** * Perform setup */ public function setUp() { parent::setUp(); $this->_commentModule = P4Cms_Module::fetch('Comment'); $this->_commentModule->enable(); $this->_commentModule->load(); } /** * Create a type and a entry for testing. * * @param integer $includeId Flag whether to include id */ public function _createTestTypeAndEntry($includeId = false) { $elements = array( 'title' => array( 'type' => 'text', 'options' => array('label' => 'Title', 'required' => true), ), 'body' => array( 'type' => 'textarea', 'options' => array('label' => 'Body'), ), 'abstract' => array( 'type' => 'textarea', 'options' => array('label' => 'Abstract'), ), ); if ($includeId) { $elements['id'] = array( 'type' => 'text', 'options' => array('label' => 'ID', 'required' => true) ); } $type = new P4Cms_Content_Type; $type->setId("test-type") ->setLabel("Test Type") ->setElements($elements) ->setValue('icon', file_get_contents(TEST_ASSETS_PATH . '/images/content-type-icon.png')) ->setFieldMetadata('icon', array("mimeType" => "image/png")) ->save(); $entry = new P4Cms_Content; $entry->setContentType($type) ->setValue('title', 'Test Title') ->setValue('body', 'The body of the test') ->setValue('abstract', 'abstract this'); if ($includeId) { $entry->setId('theId'); } $entry->save('a test entry'); return array($type, $entry); } /** * Utility function to create a pending comment. * * @param string $commentContent The string to use for the comment body. * @return string The id of the newly created comment. */ public function _createComment($commentContent) { list($type, $entry) = $this->_createTestTypeAndEntry(); $comment = new Comment_Model_Comment; $id = trim('content/' . $entry->getId(), '\\/') . '/' . (string) new P4Cms_Uuid; $params = array( 'path' => 'content%2F' . $entry->getId(), 'comment' => $commentContent ); $comment->setValues($params) ->setValue('user', P4Cms_User::fetchActive()->getId()) ->setValue('postTime', time()) ->setValue('status', Comment_Model_Comment::STATUS_PENDING) ->setId($id) ->save(); return $id; } /** * Test the post action without a path specified */ public function testEmptyCommentList() { $this->utility->impersonate('anonymous'); list($type, $entry) = $this->_createTestTypeAndEntry(true); $this->dispatch('/content/view/id/'. $entry->getId()); $body = $this->response->getBody(); $this->assertModule('content', __LINE__ .': Last module run should be content module.' . $body); $this->assertController('index', __LINE__ .': Expected controller' . $body); $this->assertAction('view', __LINE__ .': Expected action' . $body); $this->assertQuery('div.comments', 'Expected comments container.' . $body); $this->assertQueryContentContains('span.comment-count', '(0)', 'Expected zero comments.' . $body); $this->assertNotQueryContentContains( 'ul.comment-list', 'li', 'Expected empty comment list.' . $body ); $this->assertQuery( 'div' . '[href="/comment/post/format/partial?path=content%2F'.$entry->getId().'"]', 'Expected form content pane with correct href attribute.' . $body ); } /** * Test getting the form for authenticated users. */ public function testGetAuthenticatedForm() { $this->utility->impersonate('author'); list($type, $entry) = $this->_createTestTypeAndEntry(true); $this->dispatch('/comment/post/format/partial?path=content%2F'.$entry->getId()); $body = $this->response->getBody(); $this->assertQueryContentContains('h2', 'Post a Comment', 'Expected comment header.' . $body); $this->assertQuery('form.comment-form', 'Expected comment form. ' . $body); $this->assertQuery('dl.zend_form_dojo', 'Expected zend form elemement list.' . $body); $this->assertQuery('input#path[type="hidden"]', 'Expected path input element. ' .$body); $this->assertQuery('textarea#comment', 'Expected comment textarea element. ' .$body); } /** * Test getting the form for anonymous users. */ public function testGetAnonymousForm() { $this->utility->impersonate('anonymous'); list($type, $entry) = $this->_createTestTypeAndEntry(true); $this->dispatch('/comment/post/format/partial?path=content%2F'.$entry->getId()); $body = $this->response->getBody(); $this->assertQueryContentContains('h2', 'Post a Comment', 'Expected comment header.' . $body); $this->assertQuery('form.comment-form', 'Expected comment form. ' . $body); $this->assertQuery('dl.zend_form_dojo', 'Expected zend form elemement list.' . $body); $this->assertQuery('input#path[type="hidden"]', 'Expected path input element. ' .$body); $this->assertQuery('input#name[type="text"]', 'Expected name input element. ' .$body); $this->assertQuery('input#email[type="text"]', 'Expected email input element. ' .$body); $this->assertQuery('textarea#comment', 'Expected comment textarea element. ' .$body); $this->assertQuery('dd#captcha-element', 'Expected captcha element. ' .$body); } /** * Test adding a comment. */ public function testAddMemberComment() { $this->utility->impersonate('author'); list($type, $entry) = $this->_createTestTypeAndEntry(); $params = array( 'path' => 'content%2F' . $entry->getId(), 'comment' => 'Test comment.' ); $this->request->setMethod('POST'); $this->request->setPost($params); $path = 'content%2F' . $entry->getId(); $this->dispatch('/comment/post/format/partial?path=' . $path); $body = $this->response->getBody(); $this->assertModule('comment', 'Expected comment module. ' . $body); $this->assertController('index', 'Expected index controller. ' . $body); $this->assertACtion('post', 'Expected post action. ' . $body); $filter = new P4Cms_Record_Filter; $filter->add('status', Comment_Model_Comment::STATUS_APPROVED); $comments = Comment_Model_Comment::fetchAll( array( 'paths' => array('content/' . $entry->getId() . '/...') ) ); $this->assertSame(count($comments), 1, 'Expected one comment, found ' . count($comments). '.'); } /** * Test deleting conent; verify by attempting to fetch. */ public function testDeleteContent() { $id = $this->_createComment('Test comment, to be deleted.'); $this->utility->impersonate('administrator'); $this->request->setMethod('POST'); $this->request->setPost(array('id' => $id)); $this->dispatch('/comment/index/delete/'); $body = $this->response->getBody(); $this->assertModule('comment', 'Expected comment module. ' . $body); $this->assertController('index', 'Expected index controller. ' . $body); $this->assertACtion('delete', 'Expected delete action. ' . $body); try { $comment = Comment_Model_Comment::fetch($id); } catch (P4Cms_Record_NotFoundException $e) { // expected exception return; } $this->fail('Expected P4Cms_Record_NotFoundException was not raised.'); } /** * Test the manage interface by loading it and verifying that it contains what we expect. */ public function testManageGrid() { $this->utility->impersonate('administrator'); $this->dispatch('/comment/index/moderate/'); $body = $this->response->getBody(); $this->assertModule('comment', 'Expected comment module. ' . $body); $this->assertController('index', 'Expected index controller. ' . $body); $this->assertACtion('moderate', 'Expected moderate action. ' . $body); $this->assertXpath( '//div[@dojotype="dojox.data.QueryReadStore"]', 'Expected dojo.data div.' . $body ); $this->assertXpath( '//table[@dojotype="p4cms.ui.grid.DataGrid" and @jsid="p4cms.comment.grid.instance"]', 'Expected dojox.grid table.' . $body ); } /** * Test the content that populates the manage data grid */ public function testManageGridContent() { $this->utility->impersonate('administrator'); $commentCount = 5; for ($x = 0; $x < $commentCount; $x++) { $this->_createComment('Test comment #' . $x . '.'); } $this->dispatch('/comment/index/moderate/format/json'); $body = $this->response->getBody(); $this->assertModule('comment', 'Expected comment module. ' . $body); $this->assertController('index', 'Expected index controller. ' . $body); $this->assertACtion('moderate', 'Expected moderate action. ' . $body); $data = Zend_Json::decode($body); $this->assertSame( $commentCount, count($data['items']), 'Expected ' . $commentCount . ' comments.' ); } /** * Test changing the status of a comment from pending to approved */ public function testStatusChange() { $this->utility->impersonate('administrator'); $id = $this->_createComment('Test Content'); $this->request->setMethod('POST'); $this->request->setPost( array('id' => $id, 'state' => Comment_Model_Comment::STATUS_APPROVED) ); $this->dispatch('/comment/index/status'); $body = $this->response->getBody(); $comment = Comment_Model_Comment::fetch($id); $this->assertSame( $comment->getValue('status'), Comment_Model_Comment::STATUS_APPROVED, 'Expected comment to be approved' ); } /** * Test upvote. */ public function testVoteUpAction() { $this->utility->impersonate('administrator'); $id = $this->_createComment('Test Content'); $this->dispatch('/comment/index/vote-up/format/json?id=' . $id); $body = $this->response->getBody(); $this->assertModule('comment', 'Expected comment module. ' . $body); $this->assertController('index', 'Expected index controller. ' . $body); $this->assertACtion('vote-up', 'Expected moderate action. ' . $body); $comment = Comment_Model_Comment::fetch($id); $this->assertSame( $comment->getValue('votes'), 1, 'Expected comment to be approved' ); } /** * Test downvote. */ public function testVoteDownAction() { $this->utility->impersonate('administrator'); $id = $this->_createComment('Test Content'); $this->dispatch('/comment/index/vote-down/format/json?id=' . $id); $body = $this->response->getBody(); $this->assertModule('comment', 'Expected comment module. ' . $body); $this->assertController('index', 'Expected index controller. ' . $body); $this->assertACtion('vote-down', 'Expected moderate action. ' . $body); $comment = Comment_Model_Comment::fetch($id); $this->assertSame( $comment->getValue('votes'), -1, 'Expected comment to be approved' ); } /** * Test getting comments a user has voted on for a given path. */ public function testFetchVotedComments() { $this->utility->impersonate('member'); $user = $this->p4->getUser(); $path = 'test/path'; // create a handful of comments. for ($i = 0; $i < 5; $i++) { Comment_Model_Comment::store( array( 'id' => $path . '/' . $i, 'comment' => 'testing' ) ); } // user should not have voted at all yet. $voted = Comment_Model_Comment::fetchVotedComments($user, $path); $this->assertSame(0, $voted->count()); // vote once. $this->dispatch('/comment/index/vote-up/format/json?id=' . $path . '/0'); $voted = Comment_Model_Comment::fetchVotedComments($user, $path); $this->assertSame(1, $voted->count()); // vote again. $this->dispatch('/comment/index/vote-up/format/json?id=' . $path . '/1'); $voted = Comment_Model_Comment::fetchVotedComments($user, $path); $this->assertSame(2, $voted->count()); // verify path counts. $voted = Comment_Model_Comment::fetchVotedComments($user, $path . '/woozle'); $this->assertSame(0, $voted->count()); } }