ContextSwitchTest.php 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Controller
  17. * @subpackage UnitTests
  18. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id$
  21. */
  22. // Call Zend_Controller_Action_Helper_ContextSwitchTest::main() if this source file is executed directly.
  23. if (!defined("PHPUnit_MAIN_METHOD")) {
  24. require_once dirname(__FILE__) . '/../../../../TestHelper.php';
  25. define("PHPUnit_MAIN_METHOD", "Zend_Controller_Action_Helper_ContextSwitchTest::main");
  26. }
  27. require_once "PHPUnit/Framework/TestCase.php";
  28. require_once "PHPUnit/Framework/TestSuite.php";
  29. require_once 'Zend/Controller/Action/Helper/ContextSwitch.php';
  30. require_once 'Zend/Config.php';
  31. require_once 'Zend/Controller/Action.php';
  32. require_once 'Zend/Controller/Action/HelperBroker.php';
  33. require_once 'Zend/Controller/Front.php';
  34. require_once 'Zend/Controller/Request/Http.php';
  35. require_once 'Zend/Controller/Response/Cli.php';
  36. require_once 'Zend/Json.php';
  37. require_once 'Zend/Layout.php';
  38. require_once 'Zend/View.php';
  39. require_once 'Zend/View/Interface.php';
  40. /**
  41. * Test class for Zend_Controller_Action_Helper_ContextSwitch.
  42. *
  43. * @category Zend
  44. * @package Zend_Controller
  45. * @subpackage UnitTests
  46. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  47. * @license http://framework.zend.com/license/new-bsd New BSD License
  48. * @group Zend_Controller
  49. * @group Zend_Controller_Action
  50. * @group Zend_Controller_Action_Helper
  51. */
  52. class Zend_Controller_Action_Helper_ContextSwitchTest extends PHPUnit_Framework_TestCase
  53. {
  54. /**
  55. * Runs the test methods of this class.
  56. *
  57. * @access public
  58. * @static
  59. */
  60. public static function main()
  61. {
  62. require_once "PHPUnit/TextUI/TestRunner.php";
  63. $suite = new PHPUnit_Framework_TestSuite("Zend_Controller_Action_Helper_ContextSwitchTest");
  64. $result = PHPUnit_TextUI_TestRunner::run($suite);
  65. }
  66. /**
  67. * Sets up the fixture, for example, open a network connection.
  68. * This method is called before a test is executed.
  69. *
  70. * @return void
  71. */
  72. public function setUp()
  73. {
  74. Zend_Controller_Action_Helper_ContextSwitchTest_LayoutOverride::resetMvcInstance();
  75. Zend_Controller_Action_HelperBroker::resetHelpers();
  76. $this->front = Zend_Controller_Front::getInstance();
  77. $this->front->resetInstance();
  78. $this->front->addModuleDirectory(dirname(__FILE__) . '/../../_files/modules');
  79. $this->layout = Zend_Layout::startMvc();
  80. $this->helper = new Zend_Controller_Action_Helper_ContextSwitch();
  81. Zend_Controller_Action_HelperBroker::addHelper($this->helper);
  82. $this->request = new Zend_Controller_Request_Http();
  83. $this->response = new Zend_Controller_Response_Cli();
  84. $this->front->setRequest($this->request)
  85. ->setResponse($this->response)
  86. ->addControllerDirectory(dirname(__FILE__));
  87. $this->view = new Zend_View();
  88. $this->viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
  89. $this->viewRenderer->setView($this->view);
  90. $this->controller = new Zend_Controller_Action_Helper_ContextSwitchTestController(
  91. $this->request,
  92. $this->response,
  93. array()
  94. );
  95. $this->controller->setupContexts();
  96. $this->helper->setActionController($this->controller);
  97. }
  98. /**
  99. * Tears down the fixture, for example, close a network connection.
  100. * This method is called after a test is executed.
  101. *
  102. * @return void
  103. */
  104. public function tearDown()
  105. {
  106. }
  107. public function testDirectReturnsObjectInstance()
  108. {
  109. $helper = $this->helper->direct();
  110. $this->assertSame($this->helper, $helper);
  111. }
  112. public function testSetSuffixModifiesContextSuffix()
  113. {
  114. $this->helper->setSuffix('xml', 'foobar');
  115. $this->assertContains('foobar', $this->helper->getSuffix('xml'));
  116. }
  117. public function testSetSuffixPrependsToViewRendererSuffixByDefault()
  118. {
  119. $this->helper->setSuffix('xml', 'foobar');
  120. $expected = 'foobar.' . $this->viewRenderer->getViewSuffix();
  121. $this->assertContains($expected, $this->helper->getSuffix('xml'));
  122. }
  123. public function testCanSetSuffixWithoutViewRendererSuffix()
  124. {
  125. $this->helper->setSuffix('xml', 'foobar', false);
  126. $expected = 'foobar';
  127. $this->assertContains($expected, $this->helper->getSuffix('xml'));
  128. }
  129. public function testSuffixAccessorsThrowExceptionOnInvalidContextType()
  130. {
  131. try {
  132. $this->helper->setSuffix('foobar', 'foobar');
  133. $this->fail('setSuffix() should throw exception with invalid context type');
  134. } catch (Zend_Controller_Action_Exception $e) {
  135. $this->assertContains('Cannot set suffix', $e->getMessage());
  136. }
  137. try {
  138. $this->helper->getSuffix('foobar');
  139. $this->fail('getSuffix() should throw exception with invalid context type');
  140. } catch (Zend_Controller_Action_Exception $e) {
  141. $this->assertContains('Cannot retrieve suffix', $e->getMessage());
  142. }
  143. }
  144. public function testCanAddAdditionalHeadersPerContext()
  145. {
  146. $this->helper->addHeader('xml', 'X-Foo', 'Bar');
  147. $headers = $this->helper->getHeaders('xml');
  148. $this->assertTrue(isset($headers['Content-Type']));
  149. $this->assertEquals('application/xml', $headers['Content-Type']);
  150. $this->assertTrue(isset($headers['X-Foo']));
  151. $this->assertEquals('Bar', $headers['X-Foo']);
  152. }
  153. public function testCanAddMultipleHeadersPerContextSimultaneously()
  154. {
  155. $this->helper->addHeaders('xml', array(
  156. 'X-Foo' => 'Bar',
  157. 'X-Bar' => 'Baz'
  158. ));
  159. $headers = $this->helper->getHeaders('xml');
  160. $this->assertTrue(isset($headers['Content-Type']));
  161. $this->assertEquals('application/xml', $headers['Content-Type']);
  162. $this->assertTrue(isset($headers['X-Foo']));
  163. $this->assertEquals('Bar', $headers['X-Foo']);
  164. $this->assertTrue(isset($headers['X-Bar']));
  165. $this->assertEquals('Baz', $headers['X-Bar']);
  166. }
  167. public function testAddHeaderThrowsExceptionWhenReferencingExistingHeader()
  168. {
  169. try {
  170. $this->helper->addHeader('xml', 'Content-Type', 'application/xml');
  171. $this->fail('addHeader() should raise exception for existing headers');
  172. } catch (Zend_Controller_Exception $e) {
  173. $this->assertContains('already exists', $e->getMessage());
  174. }
  175. }
  176. public function testSetHeaderOverwritesHeaderExistingHeader()
  177. {
  178. $this->helper->setHeader('xml', 'Content-Type', 'application/foo-xml');
  179. $this->assertEquals('application/foo-xml', $this->helper->getHeader('xml', 'Content-Type'));
  180. }
  181. public function testSetHeadersOverwritesHeaders()
  182. {
  183. $headers = array(
  184. 'X-Foo' => 'Bar',
  185. 'X-Bar' => 'Baz'
  186. );
  187. $this->helper->setHeaders('xml', $headers);
  188. $this->assertEquals($headers, $this->helper->getHeaders('xml'));
  189. }
  190. public function testCanRemoveSingleHeaders()
  191. {
  192. $this->helper->addHeader('xml', 'X-Foo', 'Bar');
  193. $this->assertEquals('Bar', $this->helper->getHeader('xml', 'X-Foo'));
  194. $this->helper->removeHeader('xml', 'X-Foo');
  195. $this->assertNull($this->helper->getHeader('xml', 'X-Foo'));
  196. }
  197. public function testCanClearAllHeaders()
  198. {
  199. $this->helper->addHeader('xml', 'X-Foo', 'Bar');
  200. $expected = array('Content-Type' => 'application/xml', 'X-Foo' => 'Bar');
  201. $this->assertEquals($expected, $this->helper->getHeaders('xml'));
  202. $this->helper->clearHeaders('xml');
  203. $this->assertEquals(array(), $this->helper->getHeaders('xml'));
  204. }
  205. public function testHeaderAccessorsThrowExceptionOnInvalidContextType()
  206. {
  207. try {
  208. $this->helper->addHeader('foobar', 'foobar', 'baz');
  209. $this->fail('addHeader() should throw exception with invalid context type');
  210. } catch (Zend_Controller_Action_Exception $e) {
  211. $this->assertContains('does not exist', $e->getMessage());
  212. }
  213. try {
  214. $this->helper->setHeader('foobar', 'foobar', 'baz');
  215. $this->fail('setHeader() should throw exception with invalid context type');
  216. } catch (Zend_Controller_Action_Exception $e) {
  217. $this->assertContains('does not exist', $e->getMessage());
  218. }
  219. try {
  220. $this->helper->getHeader('foobar', 'Content-Type');
  221. $this->fail('getHeader() should throw exception with invalid context type');
  222. } catch (Zend_Controller_Action_Exception $e) {
  223. $this->assertContains('does not exist', $e->getMessage());
  224. }
  225. try {
  226. $this->helper->getHeaders('foobar');
  227. $this->fail('getHeaders() should throw exception with invalid context type');
  228. } catch (Zend_Controller_Action_Exception $e) {
  229. $this->assertContains('does not exist', $e->getMessage());
  230. }
  231. try {
  232. $this->helper->addHeaders('foobar', array('X-Foo' => 'Bar'));
  233. $this->fail('addHeaders() should throw exception with invalid context type');
  234. } catch (Zend_Controller_Action_Exception $e) {
  235. $this->assertContains('does not exist', $e->getMessage());
  236. }
  237. try {
  238. $this->helper->setHeaders('foobar', array('X-Foo' => 'Bar'));
  239. $this->fail('setHeaders() should throw exception with invalid context type');
  240. } catch (Zend_Controller_Action_Exception $e) {
  241. $this->assertContains('does not exist', $e->getMessage());
  242. }
  243. try {
  244. $this->helper->removeHeader('foobar', 'X-Foo');
  245. $this->fail('removeHeader() should throw exception with invalid context type');
  246. } catch (Zend_Controller_Action_Exception $e) {
  247. $this->assertContains('does not exist', $e->getMessage());
  248. }
  249. try {
  250. $this->helper->clearHeaders('foobar');
  251. $this->fail('clearHeaders() should throw exception with invalid context type');
  252. } catch (Zend_Controller_Action_Exception $e) {
  253. $this->assertContains('does not exist', $e->getMessage());
  254. }
  255. }
  256. public function testCanSetCallbackByContextAndTrigger()
  257. {
  258. $this->helper->setCallback('xml', 'init', 'htmlentities');
  259. $this->assertEquals('htmlentities', $this->helper->getCallback('xml', 'init'));
  260. $this->helper->setCallback('xml', 'post', array('Zend_Controller_Action_Helper_ContextSwitchTest', 'main'));
  261. $this->assertSame(array('Zend_Controller_Action_Helper_ContextSwitchTest', 'main'), $this->helper->getCallback('xml', 'post'));
  262. }
  263. public function testCanSetAllCallbacksByContext()
  264. {
  265. $callbacks = array(
  266. 'init' => 'htmlentities',
  267. 'post' => array('Zend_Loader', 'registerAutoload')
  268. );
  269. $this->helper->setCallbacks('xml', $callbacks);
  270. $returned = $this->helper->getCallbacks('xml');
  271. $this->assertSame(array_values($callbacks), array_values($returned));
  272. }
  273. public function testCanRemoveCallbackByContextAndTrigger()
  274. {
  275. $this->testCanSetCallbackByContextAndTrigger();
  276. $this->helper->removeCallback('xml', 'init');
  277. $this->assertNull($this->helper->getCallback('xml', 'init'));
  278. }
  279. public function testCanClearAllCallbacksByContext()
  280. {
  281. $this->testCanSetCallbackByContextAndTrigger();
  282. $this->helper->clearCallbacks('xml');
  283. $this->assertSame(array(), $this->helper->getCallbacks('xml'));
  284. }
  285. public function testCanAddContext()
  286. {
  287. $this->helper->addContext('foobar', array(
  288. 'suffix' => 'foo.bar',
  289. 'headers' => array('Content-Type' => 'application/x-foobar', 'X-Foo' => 'Bar'),
  290. ));
  291. $context = $this->helper->getContext('foobar');
  292. $this->assertNotNull($context);
  293. $this->assertTrue(is_array($context));
  294. $this->assertTrue(isset($context['suffix']));
  295. $this->assertTrue(isset($context['headers']));
  296. $this->assertTrue(isset($context['callbacks']));
  297. $this->assertContains('foo.bar', $context['suffix']);
  298. $this->assertEquals('application/x-foobar', $context['headers']['Content-Type']);
  299. $this->assertEquals('Bar', $context['headers']['X-Foo']);
  300. }
  301. public function testAddContextThrowsExceptionIfContextAlreadyExists()
  302. {
  303. try {
  304. $this->helper->addContext('xml', array());
  305. $this->fail('Shold not be able to add context if already exists');
  306. } catch (Zend_Controller_Exception $e) {
  307. $this->assertContains('exists', $e->getMessage());
  308. }
  309. }
  310. public function testSetContextOverwritesExistingContext()
  311. {
  312. $this->helper->setContext('xml', array());
  313. $this->assertNull($this->helper->getHeader('xml', 'Content-Type'));
  314. $this->assertEquals($this->viewRenderer->getViewSuffix(), $this->helper->getSuffix('xml'));
  315. }
  316. public function testCanAddMultipleContextsAtOnce()
  317. {
  318. $this->helper->addContexts(array(
  319. 'foobar' => array(
  320. 'suffix' => 'foo.bar',
  321. 'headers' => array('Content-Type' => 'application/x-foobar', 'X-Foo' => 'Bar'),
  322. ),
  323. 'barbaz' => array(
  324. 'suffix' => 'bar.baz',
  325. 'headers' => array('Content-Type' => 'application/x-barbaz', 'X-Bar' => 'Baz'),
  326. )
  327. ));
  328. $this->assertTrue($this->helper->hasContext('foobar'));
  329. $this->assertTrue($this->helper->hasContext('barbaz'));
  330. }
  331. public function testCanOverwriteManyContextsAtOnce()
  332. {
  333. $this->helper->setContexts(array(
  334. 'xml' => array(
  335. 'suffix' => array('suffix' => 'xml', 'prependViewRendererSuffix' => false),
  336. 'headers' => array('Content-Type' => 'application/xml'),
  337. 'callbacks' => array('TRIGGER_INIT' => 'foobar')
  338. ),
  339. 'foobar' => array(
  340. 'suffix' => 'foo.bar',
  341. 'headers' => array('Content-Type' => 'application/x-foobar', 'X-Foo' => 'Bar'),
  342. ),
  343. 'barbaz' => array(
  344. 'suffix' => 'bar.baz',
  345. 'headers' => array('Content-Type' => 'application/x-barbaz', 'X-Bar' => 'Baz'),
  346. )
  347. ));
  348. $this->assertTrue($this->helper->hasContext('xml'));
  349. $this->assertFalse($this->helper->hasContext('json'));
  350. $this->assertTrue($this->helper->hasContext('foobar'));
  351. $this->assertTrue($this->helper->hasContext('barbaz'));
  352. $this->assertEquals('xml', $this->helper->getSuffix('xml'));
  353. $this->assertNotEquals('foo.bar', $this->helper->getSuffix('foobar'));
  354. $this->assertContains('foo.bar', $this->helper->getSuffix('foobar'));
  355. $this->assertNotEquals('bar.baz', $this->helper->getSuffix('barbaz'));
  356. $this->assertContains('bar.baz', $this->helper->getSuffix('barbaz'));
  357. }
  358. public function testCanRemoveSingleContext()
  359. {
  360. $this->assertTrue($this->helper->hasContext('xml'));
  361. $this->helper->removeContext('xml');
  362. $this->assertFalse($this->helper->hasContext('xml'));
  363. }
  364. public function testCanClearAllContexts()
  365. {
  366. $this->assertTrue($this->helper->hasContext('xml'));
  367. $this->assertTrue($this->helper->hasContext('json'));
  368. $contexts = $this->helper->getContexts();
  369. $this->helper->clearContexts();
  370. $received = $this->helper->getContexts();
  371. $this->assertNotEquals($contexts, $received);
  372. $this->assertTrue(empty($received));
  373. }
  374. public function testDefaultContextParam()
  375. {
  376. $this->assertEquals('format', $this->helper->getContextParam());
  377. }
  378. public function testCanSetContextParam()
  379. {
  380. $this->helper->setContextParam('foobar');
  381. $this->assertEquals('foobar', $this->helper->getContextParam());
  382. }
  383. public function testDefaultContext()
  384. {
  385. $this->assertEquals('xml', $this->helper->getDefaultContext());
  386. }
  387. public function testCanSetDefaultContext()
  388. {
  389. $this->helper->setDefaultContext('json');
  390. $this->assertEquals('json', $this->helper->getDefaultContext());
  391. }
  392. public function testSetDefaultContextThrowsExceptionIfContextDoesNotExist()
  393. {
  394. try {
  395. $this->helper->setDefaultContext('foobar');
  396. $this->fail('setDefaultContext() should raise exception if context does not exist');
  397. } catch (Zend_Controller_Action_Exception $e) {
  398. $this->assertContains('Cannot set default context', $e->getMessage());
  399. }
  400. }
  401. public function testContextSwitchDisablesLayoutsByDefault()
  402. {
  403. $this->assertTrue($this->helper->getAutoDisableLayout());
  404. }
  405. public function testCanChooseWhetherLayoutsAreDisabled()
  406. {
  407. $this->helper->setAutoDisableLayout(false);
  408. $this->assertFalse($this->helper->getAutoDisableLayout());
  409. $this->helper->setAutoDisableLayout(true);
  410. $this->assertTrue($this->helper->getAutoDisableLayout());
  411. }
  412. public function checkNothingIsDone()
  413. {
  414. $this->assertEquals('phtml', $this->viewRenderer->getViewSuffix());
  415. $headers = $this->response->getHeaders();
  416. $this->assertTrue(empty($headers));
  417. }
  418. public function testInitContextDoesNothingIfNoContextsSet()
  419. {
  420. unset($this->controller->contexts);
  421. $this->request->setParam('format', 'xml')
  422. ->setActionName('foo');
  423. $this->helper->initContext();
  424. $this->checkNothingIsDone();
  425. }
  426. public function testInitContextThrowsExceptionIfControllerContextsIsInvalid()
  427. {
  428. $this->controller->contexts = 'foo';
  429. $this->request->setParam('format', 'xml')
  430. ->setActionName('foo');
  431. try {
  432. $this->helper->initContext();
  433. $this->fail('Invalid contexts array should cause failure');
  434. } catch (Zend_Controller_Exception $e) {
  435. $this->assertContains('Invalid', $e->getMessage());
  436. }
  437. $this->checkNothingIsDone();
  438. }
  439. public function testInitContextDoesNothingIfActionHasNoContexts()
  440. {
  441. $this->request->setParam('format', 'xml')
  442. ->setActionName('baz');
  443. $this->helper->initContext();
  444. $this->checkNothingIsDone();
  445. $this->request->setParam('format', 'json')
  446. ->setActionName('baz');
  447. $this->helper->initContext();
  448. $this->checkNothingIsDone();
  449. }
  450. public function testInitContextDoesNothingIfActionDoesNotHaveContext()
  451. {
  452. $this->request->setParam('format', 'json')
  453. ->setActionName('foo');
  454. $this->helper->initContext();
  455. $this->checkNothingIsDone();
  456. }
  457. public function testInitContextUsesBooleanTrueActionValueToAssumeAllContexts()
  458. {
  459. $this->request->setParam('format', 'json')
  460. ->setActionName('all');
  461. $this->helper->initContext();
  462. $this->assertEquals('json', $this->helper->getCurrentContext());
  463. $this->assertContains('json', $this->viewRenderer->getViewSuffix());
  464. $this->request->setParam('format', 'xml')
  465. ->setActionName('all');
  466. $this->helper->initContext();
  467. $this->assertEquals('xml', $this->helper->getCurrentContext());
  468. $this->assertContains('xml', $this->viewRenderer->getViewSuffix());
  469. }
  470. public function testInitContextDoesNothingIfActionDoesNotHaveContextAndPassedFormatInvalid()
  471. {
  472. $this->request->setParam('format', 'json')
  473. ->setActionName('foo');
  474. $this->helper->initContext('bogus');
  475. $this->checkNothingIsDone();
  476. }
  477. public function testInitContextSetsViewRendererViewSuffix()
  478. {
  479. $this->request->setParam('format', 'xml')
  480. ->setActionName('foo');
  481. $this->helper->initContext();
  482. $this->assertContains('xml', $this->viewRenderer->getViewSuffix());
  483. }
  484. public function testInitContextSetsAppropriateResponseHeader()
  485. {
  486. $this->request->setParam('format', 'xml')
  487. ->setActionName('foo');
  488. $this->helper->initContext();
  489. $headers = $this->response->getHeaders();
  490. $found = false;
  491. foreach ($headers as $header) {
  492. if ('Content-Type' == $header['name']) {
  493. $found = true;
  494. $value = $header['value'];
  495. }
  496. }
  497. $this->assertTrue($found);
  498. $this->assertEquals('application/xml', $value);
  499. }
  500. public function testInitContextUsesPassedFormatWhenContextParamPresent()
  501. {
  502. $this->request->setParam('format', 'xml')
  503. ->setActionName('foo');
  504. $this->helper->initContext('json');
  505. $this->assertContains('json', $this->viewRenderer->getViewSuffix());
  506. $headers = $this->response->getHeaders();
  507. $found = false;
  508. foreach ($headers as $header) {
  509. if ('Content-Type' == $header['name']) {
  510. $found = true;
  511. $value = $header['value'];
  512. }
  513. }
  514. $this->assertTrue($found);
  515. $this->assertEquals('application/json', $value);
  516. }
  517. public function testInitContextUsesPassedFormatWhenNoContextParamNotPresent()
  518. {
  519. $this->request->setActionName('foo');
  520. $this->helper->initContext('xml');
  521. $this->assertContains('xml', $this->viewRenderer->getViewSuffix());
  522. $headers = $this->response->getHeaders();
  523. $found = false;
  524. foreach ($headers as $header) {
  525. if ('Content-Type' == $header['name']) {
  526. $found = true;
  527. $value = $header['value'];
  528. }
  529. }
  530. $this->assertTrue($found);
  531. $this->assertEquals('application/xml', $value);
  532. }
  533. public function testInitContextDisablesLayoutByDefault()
  534. {
  535. $this->request->setParam('format', 'xml')
  536. ->setActionName('foo');
  537. $this->helper->initContext();
  538. $this->assertFalse($this->layout->isEnabled());
  539. }
  540. public function testInitContextDoesNotDisableLayoutIfDisableLayoutDisabled()
  541. {
  542. $this->helper->setAutoDisableLayout(false);
  543. $this->request->setParam('format', 'xml')
  544. ->setActionName('foo');
  545. $this->helper->initContext();
  546. $this->assertTrue($this->layout->isEnabled());
  547. }
  548. public function testGetCurrentContextInitiallyNull()
  549. {
  550. $this->assertNull($this->helper->getCurrentContext());
  551. }
  552. public function testGetCurrentContextReturnsContextAfterInitContextIsSuccessful()
  553. {
  554. $this->request->setParam('format', 'xml')
  555. ->setActionName('foo');
  556. $this->helper->initContext();
  557. $this->assertEquals('xml', $this->helper->getCurrentContext());
  558. }
  559. public function testGetCurrentContextResetToNullWhenSubsequentInitContextFails()
  560. {
  561. $this->assertNull($this->helper->getCurrentContext());
  562. $this->request->setParam('format', 'xml')
  563. ->setActionName('foo');
  564. $this->helper->initContext();
  565. $this->assertEquals('xml', $this->helper->getCurrentContext());
  566. $this->request->setParam('format', 'foo')
  567. ->setActionName('bogus');
  568. $this->helper->initContext();
  569. $this->assertNull($this->helper->getCurrentContext());
  570. }
  571. public function testGetCurrentContextChangesAfterSubsequentInitContextCalls()
  572. {
  573. $this->assertNull($this->helper->getCurrentContext());
  574. $this->request->setParam('format', 'xml')
  575. ->setActionName('foo');
  576. $this->helper->initContext();
  577. $this->assertEquals('xml', $this->helper->getCurrentContext());
  578. $this->request->setParam('format', 'json')
  579. ->setActionName('bar');
  580. $this->helper->initContext();
  581. $this->assertEquals('json', $this->helper->getCurrentContext());
  582. }
  583. public function testJsonContextShouldEncodeViewVariablesByDefaultAndNotRequireRenderingView()
  584. {
  585. $this->request->setParam('format', 'json')
  586. ->setActionName('bar')
  587. ->setDispatched(true);
  588. $this->controller->dispatch('barAction');
  589. $headers = $this->response->getHeaders();
  590. $found = false;
  591. foreach ($headers as $header) {
  592. if ($header['name'] == 'Content-Type') {
  593. if ($header['value'] == 'application/json') {
  594. $found = true;
  595. }
  596. break;
  597. }
  598. }
  599. $this->assertTrue($found, 'JSON content type header not found');
  600. $body = $this->response->getBody();
  601. $result = Zend_Json::decode($body);
  602. $this->assertTrue(is_array($result), var_export($body, 1));
  603. $this->assertTrue(isset($result['foo']));
  604. $this->assertTrue(isset($result['bar']));
  605. $this->assertEquals('bar', $result['foo']);
  606. $this->assertEquals('baz', $result['bar']);
  607. }
  608. public function testAutoJsonSerializationMayBeDisabled()
  609. {
  610. $this->request->setParam('format', 'json')
  611. ->setActionName('bar')
  612. ->setDispatched(true);
  613. $this->helper->setAutoJsonSerialization(false);
  614. $this->controller->dispatch('barAction');
  615. $headers = $this->response->getHeaders();
  616. $found = false;
  617. foreach ($headers as $header) {
  618. if ($header['name'] == 'Content-Type') {
  619. if ($header['value'] == 'application/json') {
  620. $found = true;
  621. }
  622. break;
  623. }
  624. }
  625. $this->assertTrue($found, 'JSON content type header not found');
  626. $body = $this->response->getBody();
  627. $this->assertTrue(empty($body), $body);
  628. }
  629. public function testCanAddOneOrMoreActionContexts()
  630. {
  631. $this->assertFalse($this->helper->hasActionContext('foo', 'json'));
  632. $this->helper->addActionContext('foo', 'json');
  633. $this->assertTrue($this->helper->hasActionContext('foo', 'json'));
  634. $this->assertFalse($this->helper->hasActionContext('baz', 'xml'));
  635. $this->assertFalse($this->helper->hasActionContext('baz', 'json'), var_export($this->controller->contexts, 1));
  636. $this->helper->addActionContext('baz', array('xml', 'json'));
  637. $this->assertTrue($this->helper->hasActionContext('baz', 'xml'));
  638. $this->assertTrue($this->helper->hasActionContext('baz', 'json'));
  639. }
  640. public function testCanOverwriteAnActionContext()
  641. {
  642. $this->assertTrue($this->helper->hasActionContext('foo', 'xml'));
  643. $this->helper->setActionContext('foo', 'json');
  644. $this->assertFalse($this->helper->hasActionContext('foo', 'xml'));
  645. $this->assertTrue($this->helper->hasActionContext('foo', 'json'));
  646. $this->helper->setActionContext('foo', array('xml', 'json'));
  647. $this->assertTrue($this->helper->hasActionContext('foo', 'json'));
  648. $this->assertTrue($this->helper->hasActionContext('foo', 'xml'));
  649. }
  650. public function testCanAddContextsForMultipleActions()
  651. {
  652. $this->assertFalse($this->helper->hasActionContext('foo', 'json'));
  653. $this->assertFalse($this->helper->hasActionContext('baz', 'json'));
  654. $this->assertFalse($this->helper->hasActionContext('baz', 'xml'));
  655. $this->helper->addActionContexts(array(
  656. 'foo' => 'json',
  657. 'baz' => array('json', 'xml'),
  658. ));
  659. $this->assertTrue($this->helper->hasActionContext('foo', 'json'));
  660. $this->assertTrue($this->helper->hasActionContext('baz', 'json'));
  661. $this->assertTrue($this->helper->hasActionContext('baz', 'xml'));
  662. }
  663. public function testCanOverwriteContextsForMultipleActions()
  664. {
  665. $this->assertTrue($this->helper->hasActionContext('foo', 'xml'));
  666. $this->assertTrue($this->helper->hasActionContext('bar', 'json'));
  667. $this->assertTrue($this->helper->hasActionContext('bar', 'xml'));
  668. $this->helper->setActionContexts(array(
  669. 'foo' => 'json',
  670. 'bar' => 'xml'
  671. ));
  672. $this->assertFalse($this->helper->hasActionContext('foo', 'xml'));
  673. $this->assertTrue($this->helper->hasActionContext('foo', 'json'));
  674. $this->assertFalse($this->helper->hasActionContext('bar', 'json'));
  675. $this->assertTrue($this->helper->hasActionContext('bar', 'xml'));
  676. }
  677. public function testCanRemoveOneOrMoreActionContexts()
  678. {
  679. $this->assertTrue($this->helper->hasActionContext('bar', 'json'));
  680. $this->assertTrue($this->helper->hasActionContext('bar', 'xml'));
  681. $this->helper->removeActionContext('bar', 'xml');
  682. $this->assertTrue($this->helper->hasActionContext('bar', 'json'));
  683. $this->assertFalse($this->helper->hasActionContext('bar', 'xml'));
  684. }
  685. public function testCanClearAllContextsForASingleAction()
  686. {
  687. $this->assertTrue($this->helper->hasActionContext('bar', 'json'));
  688. $this->assertTrue($this->helper->hasActionContext('bar', 'xml'));
  689. $this->helper->clearActionContexts('bar');
  690. $this->assertFalse($this->helper->hasActionContext('bar', 'json'));
  691. $this->assertFalse($this->helper->hasActionContext('bar', 'xml'));
  692. }
  693. public function testCanClearAllActionContexts()
  694. {
  695. $this->helper->clearActionContexts();
  696. $contexts = $this->helper->getActionContexts();
  697. $this->assertTrue(empty($contexts));
  698. }
  699. public function getOptions()
  700. {
  701. $options = array(
  702. 'contexts' => array('ajax' => array('suffix' => 'ajax', 'headers' => array('Content-Type' => 'text/x-html')), 'json' => array('suffix' => 'json', 'headers' => array('Content-Type' => 'application/json'), 'callbacks' => array('init' => 'initJsonCallback', 'post' => 'postJsonCallback'))),
  703. 'autoJsonSerialization' => false,
  704. 'suffix' => array('json' => array('suffix' => 'js', 'prependViewRendererSuffix' => false)),
  705. 'headers' => array('json' => array('Content-Type' => 'text/js')),
  706. 'callbacks' => array('json' => array('init' => 'htmlentities')),
  707. 'contextParam' => 'foobar',
  708. 'defaultContext' => 'json',
  709. 'autoDisableLayout' => false,
  710. );
  711. return $options;
  712. }
  713. public function checkOptionsAreSet()
  714. {
  715. $this->assertFalse($this->helper->getAutoJsonSerialization());
  716. $this->assertEquals('js', $this->helper->getSuffix('json'));
  717. $this->assertEquals('text/js', $this->helper->getHeader('json', 'Content-Type'));
  718. $this->assertEquals('htmlentities', $this->helper->getCallback('json', 'init'));
  719. $this->assertEquals('foobar', $this->helper->getContextParam());
  720. $this->assertEquals('json', $this->helper->getDefaultContext());
  721. $this->assertFalse($this->helper->getAutoDisableLayout());
  722. $this->assertTrue($this->helper->hasContext('ajax'));
  723. }
  724. public function testCanSetOptionsViaArray()
  725. {
  726. $this->helper->setOptions($this->getOptions());
  727. $this->checkOptionsAreSet();
  728. }
  729. public function testCanSetOptionsViaConfig()
  730. {
  731. $config = new Zend_Config($this->getOptions());
  732. $this->helper->setConfig($config);
  733. $this->checkOptionsAreSet();
  734. }
  735. public function testOptionsPassedToConstructorShouldSetInstanceState()
  736. {
  737. $this->helper = new Zend_Controller_Action_Helper_ContextSwitch($this->getOptions());
  738. $this->checkOptionsAreSet();
  739. }
  740. public function testConfigPassedToConstructorShouldSetInstanceState()
  741. {
  742. $config = new Zend_Config($this->getOptions());
  743. $this->helper = new Zend_Controller_Action_Helper_ContextSwitch($config);
  744. $this->checkOptionsAreSet();
  745. }
  746. /**
  747. * @group ZF-3279
  748. */
  749. public function testPostJsonContextDoesntThrowExceptionWhenGetVarsMethodsExists()
  750. {
  751. try {
  752. $this->helper->setAutoJsonSerialization(true);
  753. $this->helper->postJsonContext();
  754. } catch(Zend_Controller_Action_Exception $zcae) {
  755. $this->fail('Exception should be throw when view does not implement getVars() method');
  756. }
  757. }
  758. /**
  759. * @group ZF-3279
  760. */
  761. public function testPostJsonContextThrowsExceptionWhenGetVarsMethodsDoesntExist()
  762. {
  763. $view = new Zend_Controller_Action_Helper_ContextSwitchText_CustomView();
  764. $this->viewRenderer->setView($view);
  765. try {
  766. $this->helper->setAutoJsonSerialization(true);
  767. $this->helper->postJsonContext();
  768. $this->fail('Exception should be throw when view does not implement getVars() method');
  769. } catch(Zend_Controller_Action_Exception $zcae) {
  770. }
  771. }
  772. /**
  773. * @group ZF-4866
  774. */
  775. public function testForwardingShouldNotUseContextSuffixIfNewActionDoesNotDetectValidContext()
  776. {
  777. $this->request->setParam('format', 'xml')
  778. ->setActionName('foo');
  779. $this->helper->setActionContext('bar', 'json');
  780. $this->helper->initContext();
  781. $this->assertEquals('xml', $this->helper->getCurrentContext());
  782. $this->request->setActionName('bar');
  783. $this->helper->init();
  784. $this->helper->initContext();
  785. $suffix = $this->viewRenderer->getViewSuffix();
  786. $this->assertNotContains('xml', $suffix, $suffix);
  787. }
  788. /**
  789. * @group ZF-4866
  790. */
  791. public function testForwardingShouldNotPrependMultipleViewSuffixesForCustomContexts()
  792. {
  793. $this->helper->addContext('foo', array('suffix' => 'foo'));
  794. $this->helper->setActionContext('foo', 'foo');
  795. $this->helper->setActionContext('bar', 'foo');
  796. $this->request->setParam('format', 'foo')
  797. ->setActionName('foo');
  798. $this->helper->initContext();
  799. $this->assertEquals('foo', $this->helper->getCurrentContext());
  800. $suffix = $this->viewRenderer->getViewSuffix();
  801. $this->assertContains('foo', $suffix, $suffix);
  802. $this->request->setActionName('bar');
  803. $this->helper->init();
  804. $this->helper->initContext();
  805. $this->assertEquals('foo', $this->helper->getCurrentContext());
  806. $suffix = $this->viewRenderer->getViewSuffix();
  807. $this->assertContains('foo', $suffix, $suffix);
  808. $this->assertNotContains('foo.foo', $suffix, $suffix);
  809. }
  810. }
  811. class Zend_Controller_Action_Helper_ContextSwitchTestController extends Zend_Controller_Action
  812. {
  813. public $contextSwitch;
  814. /*
  815. public $contexts = array(
  816. 'foo' => array('xml'), // only XML context
  817. 'bar' => array('xml', 'json'), // only XML and JSON contexts
  818. 'baz' => array(), // no contexts
  819. 'all' => true, // all contexts
  820. );
  821. */
  822. public function setupContexts()
  823. {
  824. $this->_helper->contextSwitch()->setActionContexts(array(
  825. 'foo' => 'xml',
  826. 'bar' => array('xml', 'json'),
  827. 'all' => true
  828. ));
  829. }
  830. public function postDispatch()
  831. {
  832. $this->_helper->viewRenderer->setNoRender();
  833. }
  834. public function barAction()
  835. {
  836. $this->_helper->contextSwitch->initContext();
  837. $this->view->foo = 'bar';
  838. $this->view->bar = 'baz';
  839. }
  840. }
  841. class Zend_Controller_Action_Helper_ContextSwitchTest_LayoutOverride extends Zend_Layout
  842. {
  843. public static function resetMvcInstance()
  844. {
  845. self::$_mvcInstance = null;
  846. }
  847. }
  848. class Zend_Controller_Action_Helper_ContextSwitchText_CustomView implements Zend_View_Interface
  849. {
  850. public function getEngine()
  851. {}
  852. public function setScriptPath($path)
  853. {}
  854. public function getScriptPaths()
  855. {}
  856. public function setBasePath($path, $classPrefix = 'Zend_View')
  857. {}
  858. public function addBasePath($path, $classPrefix = 'Zend_View')
  859. {}
  860. public function __set($key, $val)
  861. {}
  862. public function __isset($key)
  863. {}
  864. public function __unset($key)
  865. {}
  866. public function assign($spec, $value = null)
  867. {}
  868. public function clearVars()
  869. {}
  870. public function render($name)
  871. {}
  872. }
  873. // Call Zend_Controller_Action_Helper_ContextSwitchTest::main() if this source file is executed directly.
  874. if (PHPUnit_MAIN_METHOD == "Zend_Controller_Action_Helper_ContextSwitchTest::main") {
  875. Zend_Controller_Action_Helper_ContextSwitchTest::main();
  876. }