ContextSwitchTest.php 36 KB

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