From caffdb4802e85c6a65e769f7ade1ce672b6833c4 Mon Sep 17 00:00:00 2001 From: Nicholas Calugar Date: Fri, 25 May 2012 13:24:08 -0700 Subject: [PATCH] Support JSONP callback in JsonStrategy --- src/Strategy/JsonStrategy.php | 13 +++++++++- test/Strategy/JsonStrategyTest.php | 40 +++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/Strategy/JsonStrategy.php b/src/Strategy/JsonStrategy.php index 65895849..aedce678 100644 --- a/src/Strategy/JsonStrategy.php +++ b/src/Strategy/JsonStrategy.php @@ -117,6 +117,13 @@ public function selectRenderer(ViewEvent $e) // application/json Accept header found return $this->renderer; } + if (0 === strpos($mediaType, 'application/javascript')) { + // application/javascript Accept header found + if (false != ($callback = $request->query()->get('callback'))) { + $this->renderer->setJsonpCallback($callback); + } + return $this->renderer; + } } } @@ -148,6 +155,10 @@ public function injectResponse(ViewEvent $e) $response = $e->getResponse(); $response->setContent($result); $headers = $response->headers(); - $headers->addHeaderLine('content-type', 'application/json'); + if ($this->renderer->hasJsonpCallback()) { + $headers->addHeaderLine('content-type', 'application/javascript'); + } else { + $headers->addHeaderLine('content-type', 'application/json'); + } } } diff --git a/test/Strategy/JsonStrategyTest.php b/test/Strategy/JsonStrategyTest.php index 757a36e0..1a9f143f 100644 --- a/test/Strategy/JsonStrategyTest.php +++ b/test/Strategy/JsonStrategyTest.php @@ -30,7 +30,8 @@ Zend\View\Model\ViewModel, Zend\View\Renderer\JsonRenderer, Zend\View\Strategy\JsonStrategy, - Zend\View\ViewEvent; + Zend\View\ViewEvent, + Zend\Stdlib\Parameters; /** * @category Zend @@ -65,6 +66,27 @@ public function testJsonAcceptHeaderSelectsJsonStrategy() $this->assertSame($this->renderer, $result); } + public function testJavascriptAcceptHeaderSelectsJsonStrategy() + { + $request = new HttpRequest(); + $request->headers()->addHeaderLine('Accept', 'application/javascript'); + $this->event->setRequest($request); + $result = $this->strategy->selectRenderer($this->event); + $this->assertSame($this->renderer, $result); + $this->assertFalse($result->hasJsonpCallback()); + } + + public function testJavascriptAcceptHeaderSelectsJsonStrategyAndSetsJsonpCallback() + { + $request = new HttpRequest(); + $request->headers()->addHeaderLine('Accept', 'application/javascript'); + $request->setQuery(new Parameters(array('callback' => 'foo'))); + $this->event->setRequest($request); + $result = $this->strategy->selectRenderer($this->event); + $this->assertSame($this->renderer, $result); + $this->assertTrue($result->hasJsonpCallback()); + } + public function testLackOfJsonModelOrAcceptHeaderDoesNotSelectJsonStrategy() { $result = $this->strategy->selectRenderer($this->event); @@ -120,6 +142,22 @@ public function testMatchingRendererAndStringResultInjectsResponse() $this->assertEquals('application/json', $headers->get('content-type')->getFieldValue()); } + public function testMatchingRendererAndStringResultInjectsResponseJsonp() + { + $expected = json_encode(array('foo' => 'bar')); + $this->renderer->setJsonpCallback('foo'); + $this->event->setResponse($this->response); + $this->event->setRenderer($this->renderer); + $this->event->setResult($expected); + + $this->strategy->injectResponse($this->event); + $content = $this->response->getContent(); + $headers = $this->response->headers(); + $this->assertEquals($expected, $content); + $this->assertTrue($headers->has('content-type')); + $this->assertEquals('application/javascript', $headers->get('content-type')->getFieldValue()); + } + public function testReturnsNullWhenCannotSelectRenderer() { $model = new ViewModel();