ContextSwitchTest.php 37 KB

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