/ */ class Category_Test_IndexControllerTest extends ModuleControllerTest { /** * Test the index action with no categories. */ public function testIndexNoCategories() { $this->utility->impersonate('anonymous'); $this->dispatch('/category/'); $body = $this->response->getBody(); $this->assertModule('category', 'Expected module.'. $body); $this->assertController('index', 'Expected controller'. $body); $this->assertAction('index', 'Expected action'. $body); $this->assertQueryContentContains('p', 'No items to display.'); } /** * Test the index action with bogus category. */ public function testIndexBogusCategory() { $this->utility->impersonate('anonymous'); $this->dispatch('/category/view/bogus'); $this->assertModule('error', 'Expected module.'); $this->assertController('index', 'Expected controller'); $this->assertAction('page-not-found', 'Expected action'); $this->assertQueryContentContains( 'p', "Sorry, the page you requested ('/category/view/bogus') does not exist." ); } /** * Test the behavior when a category has defaultContent specified. */ public function testIndexDefaultContent() { // add a type to base our test entry on. $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")) ->save(); // create content for testing $entry = new P4Cms_Content; $entry->setId('test') ->setContentType('test-type') ->setValue('title', 'title test') ->setValue('body', 'my testable body') ->save(); $orange = new P4Cms_Content; $orange->setId('orange') ->setContentType('test-type') ->setValue('title', 'an orange') ->setValue('body', 'orange body') ->save(); // create a category with defaultContent, but the content does not exist. $category1 = Category_Model_Category::store( array( 'id' => 'one', 'title' => 'First', 'indexContent' => 'bogus', ) ); $category1->addEntry('apple'); // create a category with defaultContent that exists. $category2 = Category_Model_Category::store( array( 'id' => 'two', 'title' => 'Second', 'indexContent' => 'test', ) ); $category2->addEntry('orange'); $this->utility->impersonate('anonymous'); // initial dispatch $this->dispatch('/category'); $body = $this->response->getBody(); $this->assertModule('category', 'Expected module.'. $body); $this->assertController('index', 'Expected controller'. $body); $this->assertAction('index', 'Expected action'. $body); // ensure no categories are listed yet. $this->assertQueryCount('#content .category-member', 2, 'Expected 2 categories.'); $this->assertQueryContentContains('a', 'First'); $this->assertQueryContentContains('a', 'Second'); // check again for category with bogus content $this->resetRequest()->resetResponse(); $this->dispatch('/category/view/one'); $this->assertModule('category', 'Expected module category one'); $this->assertController('index', 'Expected controller category one'); $this->assertAction('index', 'Expected action category one'); $this->assertQueryContentContains('h1', 'First'); $this->assertQueryContentContains('div[@class="category-breadcrumbs"] a', 'Categories'); $this->assertQueryContentRegex('div[@class="category-breadcrumbs"]', '/span>First/'); $this->assertQueryCount('#content .category-member', 0, 'Expected 0 entries.'); $this->assertNotQueryContentContains('a', 'apple'); // check again for category with existing content $this->resetRequest()->resetResponse(); $this->dispatch('/category/view/two'); $responseBody = $this->getResponse()->getBody(); $this->assertModule('content', 'Expected module category two.', $responseBody); $this->assertController('index', 'Expected controller category two.'. $responseBody); $this->assertAction('view', 'Expected action category two.'. $responseBody); $this->assertQueryContentContains('div[@elementname="title"]', $entry->getValue('title'), $responseBody); $this->assertQueryContentContains('div[@elementname="body"]', $entry->getValue('body'), $responseBody); } /** * Test the index action with some categories. */ public function testIndex() { // create several categories. for ($i = 1; $i <= 10; $i++) { Category_Model_Category::store( array( 'id' => "test-cat-$i", 'title' => "Test Category $i", 'description' => "a category for testing #$i", ) ); } $this->utility->impersonate('anonymous'); $this->dispatch('/category'); $this->assertModule('category', 'Expected module.'); $this->assertController('index', 'Expected controller'); $this->assertAction('index', 'Expected action'); // ensure no categories are listed yet. $this->assertQueryCount('#content .category-member', 10, 'Expected 10 categories.'); for ($i = 1; $i <= 10; $i++) { $this->assertQueryContentContains('a', "Test Category $i"); $this->assertQueryContentContains('p.description', "a category for testing #$i"); } } /** * Test the index action with nested categories/entries. */ public function testIndexNestedCategories() { // add a type to base our test entry on. $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")) ->save(); // create content for testing $entryA = new P4Cms_Content; $entryA->setId('testA') ->setContentType('test-type') ->setValue('title', 'title A') ->setValue('body', 'body A') ->save(); $entryB = new P4Cms_Content; $entryB->setId('testB') ->setContentType('test-type') ->setValue('title', 'title B') ->setValue('body', 'body B') ->save(); $entryC = new P4Cms_Content; $entryC->setId('testC') ->setContentType('test-type') ->setValue('title', 'title C') ->setValue('body', 'body C') ->save(); $entryD = new P4Cms_Content; $entryD->setId('testD') ->setContentType('test-type') ->setValue('title', 'D title') ->setValue('body', 'D body') ->save(); // create some nested categories with entries $category = Category_Model_Category::store( array( 'id' => 'one', 'title' => 'One', 'description' => 'First.', ) ); $category->addEntry('testA'); $category = Category_Model_Category::store( array( 'id' => 'one/two', 'title' => 'Two', 'description' => 'Second.', ) ); $category->addEntries(array('testB', 'testC')); $category = Category_Model_Category::store( array( 'id' => 'one/two/three', 'title' => 'Three', 'description' => 'Third.', ) ); $category->addEntry('testD'); $this->utility->impersonate('anonymous'); // first request at root level $this->dispatch('/category'); $this->assertModule('category', 'Expected module.'); $this->assertController('index', 'Expected controller'); $this->assertAction('index', 'Expected action'); // ensure expected categories are listed. $this->assertQueryCount('#content .category-member', 1, 'Expected 1 category.'); $this->assertQueryContentContains('h1', 'Categories'); $this->assertQueryContentContains('a', 'One'); $this->assertQueryContentContains('p.description', 'First.'); // reset for next request $this->resetRequest()->resetResponse(); // second request at first level $this->dispatch('/category/view/one'); $this->assertModule('category', 'Expected module 1st request'); $this->assertController('index', 'Expected controller 1st request'); $this->assertAction('index', 'Expected action 1st request'); $this->assertQueryContentContains('h1', 'One'); $this->assertQueryContentContains('p', 'First.'); $this->assertQueryContentContains('div[@class="category-breadcrumbs"] a', 'Categories'); $this->assertQueryContentRegex('div[@class="category-breadcrumbs"]', '/span>One/'); $this->assertQueryCount('#content .category-member', 2, 'Expected 2 members.'); $this->assertQueryContentContains('a', 'Two'); $this->assertQueryContentContains('p.description', 'Second.'); $this->assertQueryContentContains('a', 'title A'); // reset for next request $this->resetRequest()->resetResponse(); // second request at second level $this->dispatch('/category/view/one/two'); $this->assertModule('category', 'Expected module 2nd request'); $this->assertController('index', 'Expected controller 2nd request'); $this->assertAction('index', 'Expected action 2nd request'); $this->assertQueryContentContains('h1', 'Two'); $this->assertQueryContentContains('p', 'Second.'); $this->assertQueryContentContains('div[@class="category-breadcrumbs"] a', 'Categories'); $this->assertQueryContentContains('div[@class="category-breadcrumbs"] a', 'One'); $this->assertQueryContentRegex('div[@class="category-breadcrumbs"]', '/span>Two/'); $this->assertQueryCount('#content .category-member', 3, 'Expected 3 members.'); $this->assertQueryContentContains('a', 'Three'); $this->assertQueryContentContains('p.description', 'Third.'); $this->assertQueryContentContains('a', 'title B'); $this->assertQueryContentContains('a', 'title C'); // reset for next request $this->resetRequest()->resetResponse(); // second request at third level $this->dispatch('/category/view/one/two/three'); $this->assertModule('category', 'Expected module 3rd request.'); $this->assertController('index', 'Expected controller 3rd request'); $this->assertAction('index', 'Expected action 3rd request'); $this->assertQueryContentContains('h1', 'Three'); $this->assertQueryContentContains('p', 'Third.'); $this->assertQueryContentContains('div[@class="category-breadcrumbs"] a', 'Categories'); $this->assertQueryContentContains('div[@class="category-breadcrumbs"] a', 'One'); $this->assertQueryContentContains('div[@class="category-breadcrumbs"] a', 'Two'); $this->assertQueryContentRegex('div[@class="category-breadcrumbs"]', '/span>Three/'); $this->assertQueryCount('#content .category-member', 1, 'Expected 1 members.'); $this->assertQueryContentContains('a', 'D title'); } /** * Test escaping data in view */ public function testSecurity() { $this->utility->impersonate('administrator'); // create new category Category_Model_Category::store( array( 'id' => "test-cat", 'title' => "test & ok", 'description' => "test >> 1 & 2", ) ); // ensure category has been saved $this->assertTrue( Category_Model_Category::exists('test-cat'), "Expected existence of created category." ); // verify view is escaped $this->dispatch('/category/view/test-cat'); $responseBody = $this->response->getBody(); $this->assertModule('category', 'Expected module; '. $responseBody); $this->assertController('index', 'Expected controller; '. $responseBody); $this->assertAction('index', 'Expected action; '. $responseBody); $this->assertQueryContentRegex( 'div[@class="category-breadcrumbs"]', "/test <script>alert\('fail'\)<\/script> & ok/" ); $this->assertQueryContentRegex( 'h1[@class="category-title"]', "/test <script>alert\('fail'\)<\/script> & ok/" ); $this->assertQueryContentRegex( 'p[@class="category-description"]', "/test >> 1 & 2/" ); } }