/ * * @todo test add/edit with file fields */ class Content_Test_IndexControllerTest extends ModuleControllerTest { public $bootstrap = array('Bootstrap', 'run'); /** * Perform setup */ public function setUp() { parent::setUp(); P4Cms_Content_Type::installDefaultTypes(); // ensure a type is present for testing. $type = new P4Cms_Content_Type; $type->setId('test-type') ->setLabel('Test Type') ->setElements( array( "title" => array( "type" => "text", "options" => array("label" => "Title", "required" => true) ), "body" => array( "type" => "textarea", "options" => array("label" => "Body") ) ) ) ->setValue('icon', file_get_contents(TEST_ASSETS_PATH . "/images/content-type-icon.png")) ->setFieldMetadata('icon', array("mimeType" => "image/png")) ->setValue('group', 'test') ->save(); // ensure a type w. id is present for testing. $type = new P4Cms_Content_Type; $type->setId('test-type-w-id') ->setLabel('Test Type') ->setElements( array( "id" => array( "type" => "text", "options" => array("label" => "Title", "required" => true) ), "title" => array( "type" => "text", "options" => array("label" => "Title", "required" => true) ), "body" => array( "type" => "textarea", "options" => array("label" => "Body") ) ) ) ->setValue('icon', file_get_contents(TEST_ASSETS_PATH . "/images/content-type-icon.png")) ->setFieldMetadata('icon', array("mimeType" => "image/png")) ->setValue('group', 'test') ->save(); // ensure a type w. a file is present for testing. $type = new P4Cms_Content_Type; $type->setId('test-type-w-file') ->setLabel('Test Type') ->setElements( array( "title" => array( "type" => "text", "options" => array("label" => "Title", "required" => true) ), "name" => array( "type" => "file", "options" => array("label" => "File") ) ) ) ->setValue('icon', file_get_contents(TEST_ASSETS_PATH . "/images/content-type-icon.png")) ->setFieldMetadata('icon', array("mimeType" => "image/png")) ->setValue('group', 'test2') ->save(); } /** * Test view action. */ public function testIndex() { $this->utility->impersonate('anonymous'); $this->dispatch('/content/index'); $body = $this->response->getBody(); $this->assertModule('content', 'Last module run should be content module.'. $body); $this->assertController('index', 'Expected controller'. $body); $this->assertAction('index', 'Expected action'. $body); // check that output looks sane. $this->assertQueryContentRegex( '#content p', '/This site does not contain any content/', 'Expect the no content paragraph.' ); // create a content entry, and make sure it appears in the index. list($type, $entry) = $this->_createTestTypeAndEntry(); $this->resetRequest() ->resetResponse(); $this->dispatch('/content/index'); $this->assertModule('content', 'Last module run should be content module.'); $this->assertController('index', 'Expected controller'); $this->assertAction('index', 'Expected action'); // check that output looks correct. $this->assertQueryContentContains( '#content ul.content-list li h2 a', $entry->getValue('title'), 'Expect the correct title.' ); $this->assertQueryContentContains( '#content ul.content-list li p.content-excerpt', $entry->getValue('body'), 'Expect the correct excerpt.' ); } /** * Test the manage action. */ public function testManage() { $this->utility->impersonate('administrator'); $this->dispatch('/content/manage'); $body = $this->response->getBody(); $this->assertModule('content', 'Expected module, dispatch #1. '. $body); $this->assertController('index', 'Expected controller, dispatch #1 '. $body); $this->assertAction('manage', 'Expected action, dispatch #1 '. $body); // ensure table and dojo data elements exist $this->assertXpath('//div[@dojotype="dojox.data.QueryReadStore"]', 'Expected dojo.data div'); $this->assertXpath('//table[@dojotype="p4cms.ui.grid.DataGrid"]', 'Expected dojox.grid table'); // ensure add content button appears $this->assertXpath('//button[@class="add-button"]', 'Expected add button. '. $body); // check initial JSON output $this->resetRequest()->resetResponse(); $this->dispatch('/content/browse/format/json'); $body = $this->response->getBody(); $this->assertModule('content', 'Expected module, dispatch #2. '. $body); $this->assertController('index', 'Expected controller, dispatch #2 '. $body); $this->assertAction('browse', 'Expected action, dispatch #2 '. $body); $data = Zend_Json::decode($body); $this->assertSame( array(), $data['items'], 'Expected no items' ); // create several content entries. $expected = array(); $order = array (1, 2, 3, 4, 5, 6, 7, 8, 9); foreach ($order as $i) { $entry = new P4Cms_Content; $entry->setId("test$i") ->setValue('contentType', 'test-type') ->setValue('title', "title $i") ->setValue('file', str_repeat('.', $i)) ->save(); $expected[] = array( 'id' => "test$i", 'title' => "title $i", 'type' => array( "label" => $entry->getContentType()->getLabel(), "description" => $entry->getContentType()->getDescription(), "fields" => $entry->getContentType()->getElementNames() ), 'icon' => '/type/icon/id/test-type', 'excerpt' => "", "#REdate" => "just now", 'rawDate' => $entry->getModTime(), 'deleted' => '', 'version' => "1", 'privileges' => P4Cms_User::fetchActive()->getAllowedPrivileges("content/$i"), ); } // check again and ensure entries appear. $this->resetRequest()->resetResponse(); $this->request->setParam('sort', 'title'); $this->dispatch('/content/browse/format/json'); $body = $this->response->getBody(); $this->assertModule('content', 'Expected module, dispatch #3. '. $body); $this->assertController('index', 'Expected controller, dispatch #3 '. $body); $this->assertAction('browse', 'Expected action, dispatch #3 '. $body); $body = $this->response->getBody(); $data = Zend_Json::decode($body); // ensure that all entries in expected are contained in data items - we cannot // compare whole arrays as there might be items added by other modules foreach ($expected as $key => $expectedValues) { $this->assertEquals( $expectedValues, array_intersect($expectedValues, $data['items'][$key]), "Expected items for index: $key" ); } } /** * Test the view action. */ public function testView() { $this->utility->impersonate('anonymous'); $this->dispatch('/content/view/id/1/does not exist'); $this->assertModule('error', __LINE__ .': Last module run should be error module.'); $this->assertController('index', __LINE__ .': Expected controller'); $this->assertAction('page-not-found', __LINE__ .': Expected action'); $this->resetRequest()->resetResponse(); list($type, $entry) = $this->_createTestTypeAndEntry(); $this->dispatch('/content/view/id/'. $entry->getId()); $this->assertModule('content', __LINE__ .': Last module run should be content module.'); $this->assertController('index', __LINE__ .': Expected controller'); $this->assertAction('view', __LINE__ .': Expected action'); $this->assertQuery( 'div#content-entry-1[contentType="' . $type->getId() . '"]', __LINE__ .': Expected content-type to be specified in entry widget' ); $this->assertQueryContentContains( 'div[elementName="title"]', $entry->getValue('title'), __LINE__ .': Expected title element.' ); $this->assertQueryContentContains( 'div[elementName="body"]', $entry->getValue('body'), __LINE__ .': Expected body element.' ); $this->assertQueryContentContains( 'div[elementName="abstract"]', $entry->getValue('abstract'), __LINE__ .': Expected abstract element.' ); } /** * Test data are escaped in the view according to attached display filters. */ public function testSecurity() { $this->utility->impersonate('author'); // create content type for testing with display filters $elements = array( 'id' => array( 'type' => 'text' ), 'title' => array( 'type' => 'text', 'options' => array('label' => 'Title', 'required' => true), 'display' => array('filters' => array("HtmlSpecialChars")) ), 'body' => array( 'type' => 'textarea', 'options' => array('label' => 'Body') ) ); $type = new P4Cms_Content_Type; $type->setId("test-type") ->setLabel("Test Type") ->setElements($elements) ->save(); // ensure content is saved into perforce unescaped $title = "Escape test