/ */ class Widget_Test_IndexControllerTest extends ModuleControllerTest { /** * Clear caches prior to start of each test. */ public function setUp() { parent::setUp(); P4Cms_Widget_Type::clearCache(); // install default widgets. P4Cms_Widget::installDefaults(); } /** * Test that a bad widget request is caught. */ public function testBadIndexRequest() { // test that action requires widget param. $this->dispatch('/widget/index'); $this->assertModule('error'); $this->assertAction('error'); } /** * Test that widgets can be run properly via the controller. */ public function testGoodIndexRequest() { $id = P4Cms_Uuid::fromMd5(md5('default-test-1'))->get(); $this->dispatch('/widget/index/index/region/test/widget/' . $id); $responseBody = $this->response->getBody(); $this->assertModule('widget', 'Expected widget module.'); $this->assertController('index', 'Expected index controller.'); $this->assertAction('index', 'Expected index action.'); // check that output looks sane. $this->assertQuery('div#widget-' . $id, 'expected widget container div.'. $responseBody); $this->assertQuery('div[regionName="test"]', $responseBody); // ensure generated dialog title is as expected $widgetDialogTitleAttrPattern = 'widgetDialogTitle="Text Widget"'; $this->assertTrue( preg_match("/$widgetDialogTitleAttrPattern/", $responseBody) === 1, $responseBody ); } /** * Test that delete action rejects bad requests. */ public function testBadDeleteRequest() { $this->utility->impersonate('editor'); $this->dispatch('/widget/index/delete/region/test/widget/1'); $this->assertModule('error'); $this->assertAction('error'); } /** * Test that controller can delete widgets. */ public function testGoodDeleteRequest() { $this->utility->impersonate('editor'); $id = P4Cms_Uuid::fromMd5(md5('default-test-1'))->get(); // ensure that widget exists. try { P4Cms_Widget::fetch($id); $this->assertTrue(true, 'Expected fetch to succeed'); } catch (P4Cms_Model_NotFoundException $e) { $this->fail('Expected fetch to succeed'); } catch (Exception $e) { $this->fail(__LINE__ .' - Unpected exception: '. $e->getMessage()); } // delete it. $this->request->setMethod('POST') ->setPost(array('widget' => $id)); $this->dispatch('/widget/index/delete'); $this->assertModule('widget', 'Last module run should be widget module.'); $this->assertController('index', 'Expected controller'); $this->assertAction('delete', 'Expected action'); // ensure that widget has been deleted. try { P4Cms_Widget::fetch($id); $this->fail('Expected fetch after deletion to fail'); } catch (P4Cms_Model_NotFoundException $e) { $this->assertSame( "Cannot fetch record '$id'. Record does not exist.", $e->getMessage(), 'Expected error message' ); } catch (Exception $e) { $this->fail(__LINE__ .' - Unpected exception: '. $e->getMessage()); } } /** * Ensure add widget prompt comes up clean. */ public function testAddWidgetPrompt() { $this->utility->impersonate('editor'); $this->dispatch('/widget/index/add'); $responseBody = $this->response->getBody(); $this->assertModule('widget', 'Last module run should be widget module; '. $responseBody); $this->assertController('index', 'Expected controller; '. $responseBody); $this->assertAction('add', 'Expected action; '. $responseBody); // ensure response looks correct. $this->assertQuery('ul.widget-types', 'Expected widget types markup; '. $responseBody); $this->assertQuery('li a.add-widget[widgetType="widget/text"]', 'Expected widget type markup; '. $responseBody); // quick verification of widget order $labels = array(); foreach (P4Cms_Widget_Type::fetchAll() as $type) { $labels[] = $type->label; } $this->assertSame( array( 'Associated Categories', 'Content List', 'IFrame Widget', 'Image Rotator Widget', 'Image Widget', 'Menu Widget', 'Text Widget' ), $labels, 'Expected order of widget labels' ); } /** * Ensure widgets can be added via post request. */ public function testAddWidgetPost() { $this->utility->impersonate('editor'); // determine how many widgets currently exist in the test region. $widgets = P4Cms_Widget::fetchByRegion('test'); $widgetIds = $widgets->invoke('getId'); $count = count($widgetIds); $this->request->setMethod('POST') ->setPost( array( 'region' => 'test', 'type' => 'widget/text' ) ); $this->dispatch('/widget/index/add'); $responseBody = $this->response->getBody(); $this->assertModule('widget', 'Last module run should be widget module; '. $responseBody); $this->assertController('index', 'Expected controller; '. $responseBody); $this->assertAction('add', 'Expected action; '. $responseBody); // ensure response contains uuid of new widget $uuid = Zend_Json::decode($responseBody); $validator = new P4Cms_Uuid; $this->assertTrue($validator->isValid($uuid)); // ensure region contains correct set of widgets. $widgets = P4Cms_Widget::fetchByRegion('test'); $this->assertEquals(count($widgets), $count + 1, 'Expecting two widgets'); $this->assertTrue(P4Cms_Widget::fetch($uuid) instanceof P4Cms_Widget, 'Expecting P4Cms_Widget'); } /** * Ensure attempts to configure bogus widget fail. */ public function testBadConfigurePromptRequest() { $this->utility->impersonate('editor'); $this->dispatch('/widget/index/configure/region/test/widget/2'); $this->assertModule('error', 'Expected module'); $this->assertAction('error'); } /** * Ensure attempts to configure good widget succeed. */ public function testGoodConfigurePromptRequest() { $this->utility->impersonate('editor'); $id = P4Cms_Uuid::fromMd5(md5('default-test-1'))->get(); $this->dispatch('/widget/index/configure/region/test/widget/' . $id); $responseBody = $this->response->getBody(); $this->assertModule('widget', 'Last module run should be widget module; '. $responseBody); $this->assertController('index', 'Expected controller; '. $responseBody); $this->assertAction('configure', 'Expected action; '. $responseBody); // verify form looks correct. $this->assertQuery("form#widget-$id-config-form"); $this->assertQuery("input#widget-$id-config-region"); $this->assertQuery("input#widget-$id-config-widget"); $this->assertQuery("fieldset#widget-$id-config-general"); $this->assertQuery("fieldset#widget-$id-config-config"); $this->assertQuery("input#widget-$id-config-title"); $this->assertQuery("input#widget-$id-config-showTitle"); $this->assertQuery("input#widget-$id-config-text"); $this->assertQuery("div#widget-$id-config-text-Editor"); $this->assertQuery("button#widget-$id-config-cancel"); $this->assertQuery("input#widget-$id-config-save"); } /** * Ensure widget configuration is validated. */ public function testBadConfigureSaveRequest() { $this->utility->impersonate('editor'); $id = P4Cms_Uuid::fromMd5(md5('default-test-1'))->get(); // this request should fail because it is missing // the required title field. $this->request->setMethod('POST') ->setPost( array( 'region' => 'test', 'widget' => $id ) ); $this->dispatch('/widget/index/configure'); $this->assertModule('widget', 'Expected module'); $this->assertAction('configure'); $this->assertQuery('ul.errors'); } /** * Ensure widget configuration can be saved. */ public function testGoodConfigureSaveRequest() { $this->utility->impersonate('editor'); $id = P4Cms_Uuid::fromMd5(md5('default-test-1'))->get(); $text = 'Hello Test!' . ' - baseUrl: {{baseUrl}}' . ' - user id: {{user:id}}' . ' - user fullname: {{user:fullName}}' . ' - user email: {{user:email}}' . ' - site title: {{site:title}}' . ' - site description: {{site:description}}' . ' - site theme: {{site:theme}}' . ' - theme baseUrl: {{theme:baseUrl}}' . "\n"; $expandedText = 'Hello Test!' . ' - baseUrl: ' . ' - user id: mweiss' . ' - user fullname: Michael T. Weiss' . ' - user email: mweiss@thepretender.tv' . ' - site title: testsite' . ' - site description: description of the test site' . ' - site theme: default' . ' - theme baseUrl: /tests/phpunit/assets/sites/all/themes/default' . "\n"; $this->request->setMethod('POST') ->setPost( array( 'region' => 'test', 'widget' => $id, 'title' => 'A New Title', 'order' => '10', 'text' => $text ) ); $this->dispatch('/widget/index/configure'); $responseBody = $this->response->getBody(); $this->assertModule('widget', 'Expected widget module; '. $responseBody); $this->assertController('index', 'Expected index controller; '. $responseBody); $this->assertAction('configure', 'Expected configure action; '. $responseBody); // verify widget config has changed. $widget = P4Cms_Widget::fetch($id); $this->assertSame('test', $widget->region, 'Expected region'); $this->assertSame($id, $widget->id, 'Expected id'); $this->assertSame('A New Title', $widget->title, 'Expected title'); $this->assertSame('10', $widget->order, 'Expected order'); $this->assertEquals($text, $widget->getConfig('text'), 'Expected text'); // verify the widget renders as expected $this->dispatch('/widget/index/index/region/test/widget/' . $id); $responseBody = $this->response->getBody(); $this->assertModule('widget', 'Expected widget module.'); $this->assertController('index', 'Expected index controller.'); $this->assertAction('index', 'Expected index action.'); // check that output looks sane. $this->assertQuery('div#widget-' . $id, 'expected widget container div.'. $responseBody); $this->assertQuery('div[regionName="test"]', $responseBody); // ensure generated dialog title is as expected $widgetDialogTitleAttrPattern = 'widgetDialogTitle="Text Widget"'; $this->assertTrue( preg_match("/$widgetDialogTitleAttrPattern/", $responseBody) === 1, $responseBody ); // verify that the macros got expanded $this->assertQueryContentContains('div.widget-content', $expandedText, 'Expected content in '. $responseBody); } /** * Test escaping of various values */ public function testSecurity() { $this->utility->impersonate('editor'); $id = P4Cms_Uuid::fromMd5(md5('default-test-1'))->get(); $this->request->setMethod('POST') ->setPost( array( 'region' => 'test', 'widget' => $id, 'title' => ' & ok', 'showTitle' => '1', 'order' => '10', 'text' => 'test test 1 & 2' ) ); $this->dispatch('/widget/index/configure'); $responseBody = $this->response->getBody(); $this->assertModule('widget', 'Last module run should be widget module; '. $responseBody); $this->assertController('index', 'Expected controller; '. $responseBody); $this->assertAction('configure', 'Expected action; '. $responseBody); // ensure title and text are escaped $this->resetRequest() ->resetResponse(); $this->dispatch('/widget/index/index/region/test/widget/' . $id); $responseBody = $this->response->getBody(); $this->assertModule('widget', 'Last module run should be widget module.'); $this->assertController('index'); $this->assertAction('index'); // widget title in the html should be escaped $widgetTitleHtmlPattern = '
\s+' . '<script>alert\("test"\)<\/script> & ok'; // widget content should not be escaped as dojo editor produces html entities conversion $widgetContentHtmlPattern = '