ContextSwitchTest.php 36 KB

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