diff options
Diffstat (limited to 'tests/Controller')
-rw-r--r-- | tests/Controller/CheckRequestTest.php | 87 | ||||
-rw-r--r-- | tests/Controller/CheckResponseTest.php | 53 | ||||
-rw-r--r-- | tests/Controller/OutputTest.php | 499 | ||||
-rw-r--r-- | tests/Controller/RouteActionTest.php | 3 | ||||
-rw-r--r-- | tests/Controller/Session/FlashTest.php | 147 | ||||
-rw-r--r-- | tests/Controller/SessionTest.php | 750 | ||||
-rw-r--r-- | tests/Controller/View/TwigTest.php | 320 |
7 files changed, 1857 insertions, 2 deletions
diff --git a/tests/Controller/CheckRequestTest.php b/tests/Controller/CheckRequestTest.php new file mode 100644 index 0000000..8ba2e23 --- /dev/null +++ b/tests/Controller/CheckRequestTest.php @@ -0,0 +1,87 @@ +<?php + +namespace Jasny\Controller; + +use Psr\Http\Message\ServerRequestInterface; +use Jasny\Controller\TestHelper; + +/** + * @covers Jasny\Controller\CheckRequest + */ +class CheckRequestTest extends \PHPUnit_Framework_TestCase +{ + use TestHelper; + + /** + * Provide data for testing functions that determine request method + * + * @return array + */ + public function requestMethodProvider() + { + return [ + ['GET'], ['POST'], ['PUT'], ['DELETE'], ['HEAD'] + ]; + } + + /** + * Test functions that check request method + * + * @dataProvider requestMethodProvider + * @param string $method + */ + public function testRequestMethod($method) + { + $request = $this->createMock(ServerRequestInterface::class); + $request->method('getMethod')->will($this->returnValue($method)); + + $controller = $this->getController(['getRequest']); + $controller->method('getRequest')->will($this->returnValue($request)); + + $this->assertEquals($method === 'GET', $controller->isGetRequest()); + $this->assertEquals($method === 'POST', $controller->isPostRequest()); + $this->assertEquals($method === 'PUT', $controller->isPutRequest()); + $this->assertEquals($method === 'DELETE', $controller->isDeleteRequest()); + $this->assertEquals($method === 'HEAD', $controller->isHeadRequest()); + } + + /** + * Provide data fot testing 'getLocalReferer' function + * + * @return array + */ + public function localRefererProvider() + { + return [ + ['http://google.com/path', 'example.com', null], + ['http://example.com/', 'example.com', '/'], + ['http://www.example.com/path', 'example.com', null], + ]; + } + + /** + * Test 'getLocalReferer' funtion + * + * @dataProvider localRefererProvider + * @param string $referer + * @param string $host + * @param boolean $local + */ + public function testLocalReferer($referer, $host, $local) + { + $request = $this->createMock(ServerRequestInterface::class); + $request->expects($this->exactly(2))->method('getHeaderLine')->withConsecutive( + [$this->equalTo('HTTP_REFERER')], + [$this->equalTo('HTTP_HOST')] + )->willReturnOnConsecutiveCalls($referer, $host); + + $controller = $this->getController(['getRequest']); + $controller->method('getRequest')->will($this->returnValue($request)); + + $result = $controller->getLocalReferer(); + + $local ? + $this->assertEquals($referer, $result, "Local referer should be returned") : + $this->assertEquals('', $result, "Local referer should not be returned"); + } +} diff --git a/tests/Controller/CheckResponseTest.php b/tests/Controller/CheckResponseTest.php new file mode 100644 index 0000000..e43b5b5 --- /dev/null +++ b/tests/Controller/CheckResponseTest.php @@ -0,0 +1,53 @@ +<?php + +use Psr\Http\Message\ResponseInterface; +use Jasny\Controller\TestHelper; + +/** + * @covers Jasny\Controller\CheckResponse + */ +class ControllerTest extends PHPUnit_Framework_TestCase +{ + use TestHelper; + + /** + * Provide data for testing status methods + * + * @return array + */ + public function responseStatusProvider() + { + return [ + [null, 'successful'], + [100, 'informational'], [199, 'informational'], + [200, 'successful'], [201, 'successful'], [299, 'successful'], + [300, 'redirect'], [304, 'redirect'], [399, 'redirect'], + [400, 'client error'], [403, 'client error'], [499, 'client error'], + [500, 'server error'], [503, 'server error'], + [999, 'unkown'] + ]; + } + + /** + * Test functions that check response status code + * @dataProvider responseStatusProvider + * + * @param int $code status code + * @param string $type + */ + public function testResponseStatus($code, $type) + { + $response = $this->createMock(ResponseInterface::class); + $response->method('getStatusCode')->will($this->returnValue($code)); + + $controller = $this->getController(['getResponse']); + $controller->method('getResponse')->willReturn($response); + + $this->assertSame($type === 'informational', $controller->isInformational(), 'isInformational'); + $this->assertSame($type === 'successful', $controller->isSuccessful(), 'isSuccessful'); + $this->assertSame($type === 'redirect', $controller->isRedirection(), 'isRedirection'); + $this->assertSame($type === 'client error', $controller->isClientError(), 'isClientError'); + $this->assertSame($type === 'server error', $controller->isServerError(), 'isServerError'); + $this->assertSame(in_array($type, ['client error', 'server error']), $controller->isError(), 'isError'); + } +} diff --git a/tests/Controller/OutputTest.php b/tests/Controller/OutputTest.php new file mode 100644 index 0000000..9952d6f --- /dev/null +++ b/tests/Controller/OutputTest.php @@ -0,0 +1,499 @@ +<?php + +namespace Jasny\Controller; + +use Jasny\Controller; +use Jasny\Flash; +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\StreamInterface; +use Jasny\Controller\TestHelper; + +/** + * @covers Jasny\Controller\Output + */ +class OutputTest extends \PHPUnit_Framework_TestCase +{ + use TestHelper; + + /** + * Provide data for testing error messages functions + * + * @return array + */ + public function statusProvider() + { + return [ + ['ok', 200], + ['created', 201], + ['accepted', 202], + ['noContent', 204], + ['partialContent', 206], + + ['redirect', 303, ['example.com']], + ['back', 303], + ['notModified', 304], + + ['badRequest', 400], + ['requireAuth', 401], + ['requireLogin', 401], + ['paymentRequired', 402], + ['forbidden', 403], + ['notFound', 404], + ['conflict', 409], + ['tooManyRequests', 429] + ]; + } + + /** + * Test functions that deal with error messages + * @dataProvider statusProvider + * + * @param string $function + * @param int $code Status code + * @param array $args + */ + public function testImplicitStatus($function, $code, $args = []) + { + $response = $this->createMock(ResponseInterface::class); + $response->expects($this->once())->method('withStatus')->with($code)->willReturnSelf(); + $response->expects($this->any())->method('withHeader')->willReturnSelf(); + + $controller = $this->getController(['getResponse']); + $controller->method('getResponse')->willReturn($response); + + $controller->$function(...$args); + } + + + /** + * Test functions that deal with error messages + * @dataProvider statusProvider + * + * @param string $function + * @param int $code Status code + */ + public function testImplicitStatusMessage($function, $code, $args) + { + $message = 'Test message'; + + $stream = $this->createMock(StreamInterface::class); + $stream->expects($this->once())->method('write')->with($message); + + $response = $this->createMock(ResponseInterface::class); + $response->expects($this->once())->method('withStatus')->with($code)->willReturnSelf(); + $response->expects($this->once())->method('getBody')->willReturn($stream); + + $controller = $this->getController(['getResponse']); + $controller->method('getResponse')->willReturn($response); + + + + $this->assertEquals($result, $response, "Response object should be returned"); + } + + /** + * Test setting flash + * + * @dataProvider flashProvider + * @param object $data + */ + public function testFlash($data) + { + $controller = $this->getMockBuilder(Controller::class)->disableOriginalConstructor()->getMockForAbstractClass(); + + $flash = $controller->flash(); + $this->assertInstanceOf(Flash::class, $flash, "Flash is not set"); + $this->assertEmpty($flash->get(), "Flash data should be empty"); + + $flash = $controller->flash($data->type, $data->message); + $this->assertInstanceOf(Flash::class, $flash, "Flash is not set"); + $this->assertEquals($data, $flash->get(), "Flash data is incorrect"); + + $flash = $controller->flash(); + $this->assertInstanceOf(Flash::class, $flash, "Flash is not set"); + $this->assertEquals($data, $flash->get(), "Flash data is incorrect"); + + $flash->clear(); + } + + /** + * Test setting flash + * + * @return array + */ + public function flashProvider() + { + return [ + [(object)['type' => 'test_type', 'message' => 'Test message']] + ]; + } + + /** + * Test respondWith function + * + * @dataProvider respondWithProvider + * @param int|string $code + * @param string $format + * @param int $setCode Actual code that will be set in response + * @param string $contentType + */ + public function testRespondWith($code, $format, $setCode, $contentType) + { + $controller = $this->getController(['getResponse']); + list(, $response) = $this->getRequests(); + + $this->expectResponseWith($response, $setCode, $contentType); + $controller->method('getResponse')->will($this->returnValue($response)); + + $result = $controller->respondWith($code, $format); + + $this->assertEquals($result, $response, "Response object should be returned"); + } + + /** + * Test function respondWith + * + * @return array + */ + public function respondWithProvider() + { + return [ + [200, 'json', 200, 'application/json'], + [200, 'application/json', 200, 'application/json'], + [204, null, 204, null], + ['204 Created', null, 204, null], + ['json', null, null, 'application/json'] + ]; + } + + /** + * Test functions that are simple wrappers around respondWith function + * + * @dataProvider respondWithWrappersProvider + * @param string $function + * @param int $code + */ + public function testResponseWithWrappers($function, $code) + { + $controller = $this->getController(['getResponse']); + list(, $response) = $this->getRequests(); + + $this->expectResponseWith($response, $code); + $controller->method('getResponse')->will($this->returnValue($response)); + + $result = $controller->{$function}(); + + $this->assertEquals($result, $response, "Response object should be returned"); + } + + /** + * Provide data for testing respondWith wrappers + * + * @return array + */ + public function respondWithWrappersProvider() + { + return [ + ['ok', 200], + ['noContent', 204] + ]; + } + + /** + * Test 'created' function + * + * @dataProvider createdProvider + * @param string $location + */ + public function testCreated($location) + { + $controller = $this->getController(['getResponse']); + list(, $response) = $this->getRequests(); + + $response->expects($this->once())->method('withStatus')->with($this->equalTo(201))->will($this->returnSelf()); + if ($location) { + $response->expects($this->once())->method('withHeader')->with($this->equalTo('Location'), $this->equalTo($location))->will($this->returnSelf()); + } + + $controller->method('getResponse')->will($this->returnValue($response)); + + $result = $controller->created($location); + + $this->assertEquals($result, $response, "Response object should be returned"); + } + + /** + * Provide data for testing 'created' function + * + * @return array + */ + public function createdProvider() + { + return [ + [''], ['/some-path/test'] + ]; + } + + /** + * Test 'redirect' function + * + * @dataProvider redirectProvider + * @param string $url + * @param int $code + * @param boolean $default + */ + public function testRedirect($url, $code, $default) + { + $controller = $this->getController(['getResponse']); + list(, $response) = $this->getRequests(); + + $this->expectRedirect($response, $url, $code); + $controller->method('getResponse')->will($this->returnValue($response)); + + $result = $default ? + $controller->redirect($url) : + $controller->redirect($url, $code); + + $this->assertEquals($result, $response, "Response object should be returned"); + } + + /** + * Provide data for testing 'redirect' function + * + * @return array + */ + public function redirectProvider() + { + return [ + ['/test-url', 303, true], + ['/test-url', 301, false] + ]; + } + + /** + * Test 'requireLogin' function + * + * @dataProvider requireLoginProvider + * @param string $function + */ + public function testRequireLogin($function) + { + $controller = $this->getController(['getResponse']); + list(, $response) = $this->getRequests(); + + $this->expectRedirect($response, '/401', 303); + $controller->method('getResponse')->will($this->returnValue($response)); + + $result = $controller->{$function}(); + + $this->assertEquals($result, $response, "Response object should be returned"); + } + + /** + * Provide data for testing 'requireLogon' function + * + * @return array + */ + public function requireLoginProvider() + { + return [ + ['requireLogin'], ['requireAuth'] + ]; + } + + /** + * Test 'getLocalReferer' funtion + * + * @dataProvider localRefererProvider + * @param string $referer + * @param string $host + * @param boolean $local + */ + public function testLocalReferer($referer, $host, $local) + { + $controller = $this->getController(['getRequest']); + list($request) = $this->getRequests(); + + $this->expectLocalReferer($request, $referer, $host); + $controller->method('getRequest')->will($this->returnValue($request)); + + $result = $controller->getLocalReferer(); + + $local ? + $this->assertEquals($referer, $result, "Local referer should be returned") : + $this->assertEquals('', $result, "Local referer should not be returned"); + } + + /** + * Test 'back' function + * + * @dataProvider localRefererProvider + * @param string $referer + * @param string $host + * @param boolean $local + */ + public function testBack($referer, $host, $local) + { + $controller = $this->getController(['getRequest', 'getResponse']); + list($request, $response) = $this->getRequests(); + + $this->expectLocalReferer($request, $referer, $host); + $this->expectRedirect($response, $local ? $referer : '/', 303); + + $controller->method('getRequest')->will($this->returnValue($request)); + $controller->method('getResponse')->will($this->returnValue($response)); + + $result = $controller->back(); + + $this->assertEquals($result, $response, "Response object should be returned"); + } + + /** + * Provide data fot testing 'getLocalReferer' function + * + * @return array + */ + public function localRefererProvider() + { + return [ + ['http://not-local-host.com/path', 'local-host.com', false], + ['http://local-host.com/path', 'local-host.com', true] + ]; + } + + /** + * Expect for 'getLocalReferer' function to work correctly + * + * @param ServerRequestInterface $request + * @param string $referer + * @param string $host + */ + public function expectLocalReferer($request, $referer, $host) + { + $request->expects($this->exactly(2))->method('getHeaderLine')->withConsecutive( + [$this->equalTo('HTTP_REFERER')], + [$this->equalTo('HTTP_HOST')] + )->will($this->returnCallback(function($header) use ($referer, $host) { + return $header === 'HTTP_REFERER' ? $referer : $host; + })); + } + + /** + * Expect for redirect + * + * @param ResponseInterface $response + * @param string $url + * @param int $code + */ + public function expectRedirect($response, $url, $code) + { + $stream = $this->createMock(StreamInterface::class); + $stream->expects($this->once())->method('write')->with($this->equalTo('You are being redirected to <a href="' . $url . '">' . $url . '</a>')); + + $response->expects($this->once())->method('getBody')->will($this->returnValue($stream)); + $response->expects($this->once())->method('withStatus')->with($this->equalTo($code))->will($this->returnSelf()); + $response->expects($this->exactly(2))->method('withHeader')->withConsecutive( + [$this->equalTo('Content-Type'), $this->equalTo('text/html')], + [$this->equalTo('Location'), $this->equalTo($url)] + )->will($this->returnSelf()); + } + + /** + * Expect correct work of respondWith function + * + * @param ResponseInterface $response + * @param int $code + * @param string $contentType + */ + public function expectResponseWith($response, $code, $contentType = null) + { + $code ? + $response->expects($this->once())->method('withStatus')->with($this->equalTo($code))->will($this->returnSelf()) : + $response->expects($this->never())->method('withStatus')->with($this->equalTo($code)); + + $contentType ? + $response->expects($this->once())->method('withHeader')->with($this->equalTo('Content-Type'), $this->equalTo($contentType))->will($this->returnSelf()) : + $response->expects($this->never())->method('withHeader')->with($this->equalTo('Content-Type'), $this->equalTo($contentType)); + } + + /** + * Expects that output will be set to content + * + * @param ResponseInterface $response + * @param string $content + * @param string $contentType + */ + public function expectOutput($response, $content, $contentType) + { + $stream = $this->createMock(StreamInterface::class); + $stream->expects($this->once())->method('write')->with($this->equalTo($content)); + + $response->expects($this->once())->method('withHeader')->with($this->equalTo('Content-Type'), $this->equalTo($contentType))->will($this->returnSelf()); + $response->expects($this->once())->method('getBody')->will($this->returnValue($stream)); + } + + /** + * Provide data for testing output + * + * @return array + */ + public function outputProvider() + { + $xml = simplexml_load_string( + "<?xml version='1.0'?> + <document> + <tag1>Test tag</tag1> + <tag2>Test</tag2> + </document>" + ); + + return [ + ['test_string', 'text', 'text/plain'], + ['javascript:test_call();', 'js', 'application/javascript'], + ['test {}', 'css', 'text/css'], + ['{ "testKey": "testValue" }', 'json', 'application/json'], + [['testKey' => 'testValue'], 'json', 'application/json'], + [$xml, 'xml', 'application/xml'] + ]; + } + + /** + * Test output + * + * @dataProvider outputProvider + * @param mixed $data + * @param string $format + * @param string $contentType + */ + public function testOutput($data, $format, $contentType) + { + $response = $this->createMock(ResponseInterface::class); + + $controller = $this->getController(['getResponse']); + $controller->method('getResponse')->willReturn($response); + + if (is_scalar($data)) { + $content = $data; + } elseif ($format === 'json') { + $content = json_encode($data); + + if ($callback) $content = "$callback($content)"; + } elseif ($format === 'xml') { + $content = $data->asXML(); + } + + $this->expectOutput($response, $content, $contentType); + + if ($callback) { + $request->method('getQueryParams')->will($this->returnValue(['callback' => $callback])); + } + + $controller->method('getRequest')->will($this->returnValue($request)); + $controller->method('getResponse')->will($this->returnValue($response)); + + $result = $controller->output($data, $format); + + $this->assertEquals($result, $response, "Output should return response instance"); + } +} diff --git a/tests/Controller/RouteActionTest.php b/tests/Controller/RouteActionTest.php index edc4bd7..cd630e0 100644 --- a/tests/Controller/RouteActionTest.php +++ b/tests/Controller/RouteActionTest.php @@ -1,7 +1,6 @@ <?php -require_once dirname(__DIR__) . '/support/TestController.php'; - +use Jasny\Controller; use Jasny\Controller\RouteAction; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; diff --git a/tests/Controller/Session/FlashTest.php b/tests/Controller/Session/FlashTest.php new file mode 100644 index 0000000..c17c446 --- /dev/null +++ b/tests/Controller/Session/FlashTest.php @@ -0,0 +1,147 @@ +<?php + +use Jasny\Flash; + +/** + * @covers Jasny\Flash + */ +class FlashTest extends PHPUnit_Framework_TestCase +{ + /** + * Test flash + * + * @dataProvider flashProvider + * @param object $data + */ + public function testFlash($data) + { + $flash = new Flash(); + $this->assertFlashEmpty($flash); + + //Set flash + $flash->set($data->type, $data->message); + $this->assertFlashDataCorrect($flash, $data); + $this->assertFlashIsIssued($flash, $data); + + //Get data + $setData = $flash->get(); + $this->assertFlashDataCorrect($flash, $data); + $this->assertFlashIsIssued($flash, $data); + $this->assertEquals($data, $setData, "Flash data was not got correctly"); + + //Clear + $flash->clear(); + $this->assertFlashEmpty($flash); + + //Set from session + $_SESSION['flash'] = $data; + $this->assertFlashIsIssued($flash, $data); + + //When flash is set only in session, not by 'set' method, then getting it's data removes flash from session, so they only remain in flash object + $this->assertFlashDataCorrect($flash, $data); + $this->assertFalse(isset($_SESSION['flash']), "Session flash variable should be empty"); + $this->assertTrue($flash->isIssued(), "Flash should be issued"); + + //Clear + $flash->clear(); + $this->assertFlashEmpty($flash); + + //Reissue from session + $_SESSION['flash'] = $data; + $flash->reissue(); + + $this->assertFlashDataCorrect($flash, $data); + $this->assertFlashIsIssued($flash, $data); + + //Reissue from object data + unset($_SESSION['flash']); + $flash->reissue(); + + $this->assertFlashDataCorrect($flash, $data); + $this->assertFlashIsIssued($flash, $data); + + //Clear + $flash->clear(); + $this->assertFlashEmpty($flash); + } + + /** + * Provide data for testing flash + * + * @return array + */ + public function flashProvider() + { + return [ + [(object)['type' => 'test_type', 'message' => 'Test message']], + [(object)['type' => 'test_type', 'message' => '']] + ]; + } + + /** + * Test 'set' method with wrong params + * + * @dataProvider setNegativeProvider + * @param object $data + */ + public function testSetNegative($data) + { + $flash = new Flash(); + + $this->expectException(InvalidArgumentException::class); + + $flash->set($data->type, $data->message); + } + + /** + * Provide data for testing wrong set + * + * @return array + */ + public function setNegativeProvider() + { + return [ + [(object)['type' => '', 'message' => 'Test message']] + ]; + } + + /** + * Assert that flash is not set + * + * @param Flash $flash + */ + public function assertFlashEmpty($flash) + { + $this->assertFalse(isset($_SESSION['flash']), "Session flash variable should be empty"); + $this->assertFalse($flash->isIssued(), "Flash should not be issued"); + $this->assertEmpty($flash->get(), "Flash should be empty"); + $this->assertEmpty($flash->getType(), "Flash type should not be set"); + $this->assertEmpty($flash->getMessage(), "Message should be empty"); + $this->assertEmpty((string)$flash, "Flash should be empty"); + } + + /** + * Assert that flash is issued + * + * @param Flash $flash + * @param object $data + */ + public function assertFlashIsIssued($flash, $data) + { + $this->assertEquals($data, $_SESSION['flash'], "Flash data was not set correctly"); + $this->assertTrue($flash->isIssued(), "Flash should be issued"); + } + + /** + * Assert that flash data is correct + * + * @param Flash $flash + * @param object $data + */ + public function assertFlashDataCorrect($flash, $data) + { + $this->assertEquals($data->type, $flash->getType(), "Type was not got correctly"); + $this->assertEquals($data->message, $flash->getMessage(), "Message was not got correctly"); + $this->assertEquals($data->message, (string)$flash, "Message was not got correctly when presenting flash as string"); + } +} diff --git a/tests/Controller/SessionTest.php b/tests/Controller/SessionTest.php new file mode 100644 index 0000000..b6a6b2d --- /dev/null +++ b/tests/Controller/SessionTest.php @@ -0,0 +1,750 @@ +<?php + +use Jasny\Controller; +use Jasny\Flash; +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\StreamInterface; + +/** + * @covers Jasny\Controller + */ +class ControllerTest extends PHPUnit_Framework_TestCase +{ + /** + * Get mock for controller + * + * @param array $methods Methods to mock + * @return Controller + */ + public function getController($methods = []) + { + $builder = $this->getMockBuilder(Controller::class)->disableOriginalConstructor(); + if ($methods) { + $builder->setMethods($methods); + } + + return $builder->getMockForAbstractClass(); + } + + /** + * Test running controller + */ + public function testInvoke() + { + $test = $this; + $controller = $this->getController(); + + $request = $this->createMock(ServerRequestInterface::class); + $response = $this->createMock(ResponseInterface::class); + $finalResponse = $this->createMock(ResponseInterface::class); + + $controller->expects($this->once())->method('run') + ->willReturnCallback(Closure::bind(function() use ($test, $request, $response, $finalResponse) { + $test->assertSame($request, $this->getRequest()); + $test->assertSame($response, $this->getResponse()); + + return $finalResponse; + }, $controller, Controller::class)); + + $result = $controller($request, $response); + + $this->assertEquals($finalResponse, $result); + } + + /** + * Test response status functions if response object is not set + */ + public function testResponseStatusEmptyResponse() + { + $controller = $this->getController(); + $data = $this->getStatusCodesMap(null); + + foreach ($data as $func => $value) { + $this->assertEquals($value, $controller->$func(), "Method '$func' returns incorrect value"); + } + } + + /** + * Test functions that check response status code + * + * @dataProvider responseStatusProvider + * @param int status code + */ + public function testResponseStatus($code) + { + $controller = $this->getController(); + list($request, $response) = $this->getRequests(); + $response->method('getStatusCode')->will($this->returnValue($code)); + + $controller($request, $response); + + $data = $this->getStatusCodesMap($code); + + foreach ($data as $func => $value) { + $this->assertEquals($value, $controller->$func(), "Method '$func' returns incorrect value"); + } + + $this->assertEquals($data['isClientError'] || $data['isServerError'], $controller->isError() + , "Method 'isError' returns incorrect value"); + } + + /** + * Provide data for testing status methods + * + * @return array + */ + public function responseStatusProvider() + { + return [ + [null], [199], + [200], [201], [299], + [300], [304], [399], + [400], [403], [499], + [500], [503] + ]; + } + + /** + * Test functions that check request method + * + * @dataProvider requestMethodProvider + * @param string $method + */ + public function testRequestMethod($method) + { + $controller = $this->getController(); + list($request, $response) = $this->getRequests(); + $request->method('getMethod')->will($this->returnValue($method)); + + $controller($request, $response); + + $data = $this->getMethodsMap($method); + + foreach ($data as $func => $value) { + $this->assertEquals($value, $controller->$func(), "Method '$func' returns incorrect value"); + } + } + + /** + * Provide data for testing functions that determine request method + * + * @return array + */ + public function requestMethodProvider() + { + return [ + ['GET'], ['POST'], ['PUT'], ['DELETE'], ['HEAD'] + ]; + } + + /** + * Test encodeData method, positive tests + * + * @dataProvider encodeDataPositiveProvider + * @param mixed $data + * @param string $format + * @param string $callback Callback name for testing jsonp request + */ + public function testEncodeDataPositive($data, $format, $callback = null) + { + $this->markTestSkipped(); + + $controller = $this->getController(['getRequest']); + list($request) = $this->getRequests(); + + if ($callback) { + $request->method('getQueryParams')->will($this->returnValue(['callback' => $callback])); + } + + $controller->method('getRequest')->will($this->returnValue($request)); + + $result = $controller->encodeData($data, $format); + $expect = null; + + if ($format === 'json') { + $expect = json_encode($data); + + if ($callback) $expect = "$callback($expect)"; + } else { + $expect = $data->asXML(); + } + + $this->assertNotEmpty($result, "Result should not be empty"); + $this->assertEquals($expect, $result, "Data was not encoded correctly"); + } + + /** + * Provide data for testing encodeData method + * + * @return array + */ + public function encodeDataPositiveProvider() + { + $xml = simplexml_load_string( + "<?xml version='1.0'?> + <document> + <tag1>Test tag</tag1> + <tag2>Test</tag2> + </document>" + ); + + return [ + ['test_string', 'json'], + [['testKey' => 'testValue'], 'json'], + [['testKey' => 'testValue'], 'json', 'test_callback'], + ['', 'json'], + ['', 'json', 'test_callback'], + [$xml, 'xml'] + ]; + } + + /** + * Test encodeData method, negative tests + * + * @dataProvider encodeDataNegativeProvider + * @param mixed $data + * @param string $format + */ + public function testEncodeDataNegative($data, $format) + { + $this->markTestSkipped(); + + $controller = $this->getController(['getRequest']); + list($request) = $this->getRequests(); + + $controller->method('getRequest')->will($this->returnValue($request)); + $this->expectException(\InvalidArgumentException::class); + + $result = $controller->encodeData($data, $format); + } + + /** + * Provide data for testing encodeData method + * + * @return array + */ + public function encodeDataNegativeProvider() + { + return [ + ['test_string', 'html'], + ['test_string', 'jpg'] + ]; + } + + /** + * Test output + * + * @dataProvider outputProvider + * @param mixed $data + * @param string $format + * @param string $contentType + * @param string $callback Callback name for testing jsonp request + */ + public function testOutput($data, $format, $contentType, $callback = '') + { + $controller = $this->getController(['getRequest', 'getResponse']); + list($request, $response) = $this->getRequests(); + + if (is_scalar($data)) { + $content = $data; + } elseif ($format === 'json') { + $content = json_encode($data); + + if ($callback) $content = "$callback($content)"; + } elseif ($format === 'xml') { + $content = $data->asXML(); + } + + $this->expectOutput($response, $content, $contentType); + + if ($callback) { + $request->method('getQueryParams')->will($this->returnValue(['callback' => $callback])); + } + + $controller->method('getRequest')->will($this->returnValue($request)); + $controller->method('getResponse')->will($this->returnValue($response)); + + $result = $controller->output($data, $format); + + $this->assertEquals($result, $response, "Output should return response instance"); + } + + /** + * Provide data for testing output + * + * @return array + */ + public function outputProvider() + { + $xml = simplexml_load_string( + "<?xml version='1.0'?> + <document> + <tag1>Test tag</tag1> + <tag2>Test</tag2> + </document>" + ); + + return [ + ['test_string', 'text', 'text/plain'], + ['javascript:test_call();', 'js', 'application/javascript'], + ['test {}', 'css', 'text/css'], + ['test_string', 'json', 'application/json'], + [['testKey' => 'testValue'], 'json', 'application/json'], + [['testKey' => 'testValue'], 'json', 'application/json', 'test_callback'], + ['', 'json', 'application/json'], + ['', 'json', 'application/json', 'test_callback'], + [$xml, 'xml', 'application/xml'] + ]; + } + + /** + * Test functions that deal with error messages + * + * @dataProvider errorMessagesProvider + * @param string $function + * @param int $code + * @param boolean $default Is code default for this function + */ + public function testErrorMessages($function, $code, $default) + { + $message = 'Test message'; + $controller = $this->getController(['getResponse']); + list(, $response) = $this->getRequests(); + + $this->expectErrorMessage($response, $message, $code); + $controller->method('getResponse')->will($this->returnValue($response)); + + $result = $default ? + $controller->{$function}($message) : + $controller->{$function}($message, $code); + + $this->assertEquals($result, $response, "Response object should be returned"); + } + + /** + * Provide data for testing error messages functions + * + * @return array + */ + public function errorMessagesProvider() + { + return [ + ['error', 400, true], + ['error', 403, false], + ['tooManyRequests', 429, true], + ['tooManyRequests', 400, false], + ['conflict', 409, true], + ['conflict', 403, false], + ['notFound', 404, true], + ['notFound', 400, false], + ['forbidden', 403, true], + ['forbidden', 409, false], + ['badRequest', 400, true], + ['badRequest', 403, false] + ]; + } + + /** + * Test setting flash + * + * @dataProvider flashProvider + * @param object $data + */ + public function testFlash($data) + { + $controller = $this->getMockBuilder(Controller::class)->disableOriginalConstructor()->getMockForAbstractClass(); + + $flash = $controller->flash(); + $this->assertInstanceOf(Flash::class, $flash, "Flash is not set"); + $this->assertEmpty($flash->get(), "Flash data should be empty"); + + $flash = $controller->flash($data->type, $data->message); + $this->assertInstanceOf(Flash::class, $flash, "Flash is not set"); + $this->assertEquals($data, $flash->get(), "Flash data is incorrect"); + + $flash = $controller->flash(); + $this->assertInstanceOf(Flash::class, $flash, "Flash is not set"); + $this->assertEquals($data, $flash->get(), "Flash data is incorrect"); + + $flash->clear(); + } + + /** + * Test setting flash + * + * @return array + */ + public function flashProvider() + { + return [ + [(object)['type' => 'test_type', 'message' => 'Test message']] + ]; + } + + /** + * Test respondWith function + * + * @dataProvider respondWithProvider + * @param int|string $code + * @param string $format + * @param int $setCode Actual code that will be set in response + * @param string $contentType + */ + public function testRespondWith($code, $format, $setCode, $contentType) + { + $controller = $this->getController(['getResponse']); + list(, $response) = $this->getRequests(); + + $this->expectResponseWith($response, $setCode, $contentType); + $controller->method('getResponse')->will($this->returnValue($response)); + + $result = $controller->respondWith($code, $format); + + $this->assertEquals($result, $response, "Response object should be returned"); + } + + /** + * Test function respondWith + * + * @return array + */ + public function respondWithProvider() + { + return [ + [200, 'json', 200, 'application/json'], + [200, 'application/json', 200, 'application/json'], + [204, null, 204, null], + ['204 Created', null, 204, null], + ['json', null, null, 'application/json'] + ]; + } + + /** + * Test functions that are simple wrappers around respondWith function + * + * @dataProvider respondWithWrappersProvider + * @param string $function + * @param int $code + */ + public function testResponseWithWrappers($function, $code) + { + $controller = $this->getController(['getResponse']); + list(, $response) = $this->getRequests(); + + $this->expectResponseWith($response, $code); + $controller->method('getResponse')->will($this->returnValue($response)); + + $result = $controller->{$function}(); + + $this->assertEquals($result, $response, "Response object should be returned"); + } + + /** + * Provide data for testing respondWith wrappers + * + * @return array + */ + public function respondWithWrappersProvider() + { + return [ + ['ok', 200], + ['noContent', 204] + ]; + } + + /** + * Test 'created' function + * + * @dataProvider createdProvider + * @param string $location + */ + public function testCreated($location) + { + $controller = $this->getController(['getResponse']); + list(, $response) = $this->getRequests(); + + $response->expects($this->once())->method('withStatus')->with($this->equalTo(201))->will($this->returnSelf()); + if ($location) { + $response->expects($this->once())->method('withHeader')->with($this->equalTo('Location'), $this->equalTo($location))->will($this->returnSelf()); + } + + $controller->method('getResponse')->will($this->returnValue($response)); + + $result = $controller->created($location); + + $this->assertEquals($result, $response, "Response object should be returned"); + } + + /** + * Provide data for testing 'created' function + * + * @return array + */ + public function createdProvider() + { + return [ + [''], ['/some-path/test'] + ]; + } + + /** + * Test 'redirect' function + * + * @dataProvider redirectProvider + * @param string $url + * @param int $code + * @param boolean $default + */ + public function testRedirect($url, $code, $default) + { + $controller = $this->getController(['getResponse']); + list(, $response) = $this->getRequests(); + + $this->expectRedirect($response, $url, $code); + $controller->method('getResponse')->will($this->returnValue($response)); + + $result = $default ? + $controller->redirect($url) : + $controller->redirect($url, $code); + + $this->assertEquals($result, $response, "Response object should be returned"); + } + + /** + * Provide data for testing 'redirect' function + * + * @return array + */ + public function redirectProvider() + { + return [ + ['/test-url', 303, true], + ['/test-url', 301, false] + ]; + } + + /** + * Test 'requireLogin' function + * + * @dataProvider requireLoginProvider + * @param string $function + */ + public function testRequireLogin($function) + { + $controller = $this->getController(['getResponse']); + list(, $response) = $this->getRequests(); + + $this->expectRedirect($response, '/401', 303); + $controller->method('getResponse')->will($this->returnValue($response)); + + $result = $controller->{$function}(); + + $this->assertEquals($result, $response, "Response object should be returned"); + } + + /** + * Provide data for testing 'requireLogon' function + * + * @return array + */ + public function requireLoginProvider() + { + return [ + ['requireLogin'], ['requireAuth'] + ]; + } + + /** + * Test 'getLocalReferer' funtion + * + * @dataProvider localRefererProvider + * @param string $referer + * @param string $host + * @param boolean $local + */ + public function testLocalReferer($referer, $host, $local) + { + $controller = $this->getController(['getRequest']); + list($request) = $this->getRequests(); + + $this->expectLocalReferer($request, $referer, $host); + $controller->method('getRequest')->will($this->returnValue($request)); + + $result = $controller->getLocalReferer(); + + $local ? + $this->assertEquals($referer, $result, "Local referer should be returned") : + $this->assertEquals('', $result, "Local referer should not be returned"); + } + + /** + * Test 'back' function + * + * @dataProvider localRefererProvider + * @param string $referer + * @param string $host + * @param boolean $local + */ + public function testBack($referer, $host, $local) + { + $controller = $this->getController(['getRequest', 'getResponse']); + list($request, $response) = $this->getRequests(); + + $this->expectLocalReferer($request, $referer, $host); + $this->expectRedirect($response, $local ? $referer : '/', 303); + + $controller->method('getRequest')->will($this->returnValue($request)); + $controller->method('getResponse')->will($this->returnValue($response)); + + $result = $controller->back(); + + $this->assertEquals($result, $response, "Response object should be returned"); + } + + /** + * Provide data fot testing 'getLocalReferer' function + * + * @return array + */ + public function localRefererProvider() + { + return [ + ['http://not-local-host.com/path', 'local-host.com', false], + ['http://local-host.com/path', 'local-host.com', true] + ]; + } + + /** + * Expect for 'getLocalReferer' function to work correctly + * + * @param ServerRequestInterface $request + * @param string $referer + * @param string $host + */ + public function expectLocalReferer($request, $referer, $host) + { + $request->expects($this->exactly(2))->method('getHeaderLine')->withConsecutive( + [$this->equalTo('HTTP_REFERER')], + [$this->equalTo('HTTP_HOST')] + )->will($this->returnCallback(function($header) use ($referer, $host) { + return $header === 'HTTP_REFERER' ? $referer : $host; + })); + } + + /** + * Expect for redirect + * + * @param ResponseInterface $response + * @param string $url + * @param int $code + */ + public function expectRedirect($response, $url, $code) + { + $stream = $this->createMock(StreamInterface::class); + $stream->expects($this->once())->method('write')->with($this->equalTo('You are being redirected to <a href="' . $url . '">' . $url . '</a>')); + + $response->expects($this->once())->method('getBody')->will($this->returnValue($stream)); + $response->expects($this->once())->method('withStatus')->with($this->equalTo($code))->will($this->returnSelf()); + $response->expects($this->exactly(2))->method('withHeader')->withConsecutive( + [$this->equalTo('Content-Type'), $this->equalTo('text/html')], + [$this->equalTo('Location'), $this->equalTo($url)] + )->will($this->returnSelf()); + } + + /** + * Expect correct work of respondWith function + * + * @param ResponseInterface $response + * @param int $code + * @param string $contentType + */ + public function expectResponseWith($response, $code, $contentType = null) + { + $code ? + $response->expects($this->once())->method('withStatus')->with($this->equalTo($code))->will($this->returnSelf()) : + $response->expects($this->never())->method('withStatus')->with($this->equalTo($code)); + + $contentType ? + $response->expects($this->once())->method('withHeader')->with($this->equalTo('Content-Type'), $this->equalTo($contentType))->will($this->returnSelf()) : + $response->expects($this->never())->method('withHeader')->with($this->equalTo('Content-Type'), $this->equalTo($contentType)); + } + + /** + * Expect for correct work of error message functions + * + * @param ResponseInterface $response + * @param string $message + * @param int $code + */ + public function expectErrorMessage($response, $message, $code) + { + $stream = $this->createMock(StreamInterface::class); + $stream->expects($this->once())->method('write')->with($this->equalTo($message)); + + $response->expects($this->once())->method('withStatus')->with($this->equalTo($code))->will($this->returnSelf()); + $response->expects($this->once())->method('getBody')->will($this->returnValue($stream)); + } + + /** + * Expects that output will be set to content + * + * @param ResponseInterface $response + * @param string $content + * @param string $contentType + */ + public function expectOutput($response, $content, $contentType) + { + $stream = $this->createMock(StreamInterface::class); + $stream->expects($this->once())->method('write')->with($this->equalTo($content)); + + $response->expects($this->once())->method('withHeader')->with($this->equalTo('Content-Type'), $this->equalTo($contentType))->will($this->returnSelf()); + $response->expects($this->once())->method('getBody')->will($this->returnValue($stream)); + } + + /** + * Get request and response instances + * + * @return array + */ + public function getRequests() + { + return [ + $this->createMock(ServerRequestInterface::class), + $this->createMock(ResponseInterface::class) + ]; + } + + /** + * Get map of status codes to states + * + * @param int $code + * @return [] + */ + public function getStatusCodesMap($code) + { + return [ + 'isSuccessful' => !$code || ($code >= 200 && $code < 300), + 'isRedirection' => $code >= 300 && $code < 400, + 'isClientError' => $code >= 400 && $code < 500, + 'isServerError' => $code >= 500 + ]; + } + + /** + * Get map of request methods + * + * @param string $method + * @return array + */ + public function getMethodsMap($method) + { + return [ + 'isGetRequest' => $method === 'GET', + 'isPostRequest' => $method === 'POST', + 'isPutRequest' => $method === 'PUT', + 'isDeleteRequest' => $method === 'DELETE', + 'isHeadRequest' => $method === 'HEAD' + ]; + } +} diff --git a/tests/Controller/View/TwigTest.php b/tests/Controller/View/TwigTest.php new file mode 100644 index 0000000..662681d --- /dev/null +++ b/tests/Controller/View/TwigTest.php @@ -0,0 +1,320 @@ +<?php + +use Jasny\Flash; +use Jasny\Controller\View\Twig; +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\StreamInterface; +use Psr\Http\Message\UriInterface; + +/** + * @covers Jasny\Controller\View\Twig + */ +class TwigTest extends PHPUnit_Framework_TestCase +{ + /** + * Test creating twig environment + */ + public function testGetTwig() + { + $view = $this->getView(['getTwigLoader', 'getTwigEnvironment', 'createTwigFunction', 'createTwigFilter', 'setViewExtension', 'setViewVariable']); + list($request, $response) = $this->getRequests(); + list($loader, $env) = $this->getTwigObjects(); + + $view->expects($this->once())->method('getTwigLoader')->will($this->returnValue($loader)); + $view->expects($this->once())->method('getTwigEnvironment')->with($this->equalTo($loader))->will($this->returnValue($env)); + $view->expects($this->exactly(4))->method('setViewExtension')->with($this->callback(function($ext) { + return in_array(get_class($ext), ['Jasny\Twig\DateExtension', 'Jasny\Twig\PcreExtension', 'Jasny\Twig\TextExtension', 'Jasny\Twig\ArrayExtension'], true); + }))->will($this->returnSelf()); + + $path = '/test/request/path'; + $uri = $this->createMock(UriInterface::class); + + $view->expects($this->once())->method('getRequest')->will($this->returnValue($request)); + $request->expects($this->once())->method('getUri')->will($this->returnValue($uri)); + $uri->expects($this->once())->method('getPath')->will($this->returnValue($path)); + $view->expects($this->exactly(2))->method('setViewVariable')->withConsecutive( + [$this->equalTo('current_url'), $this->equalTo($path)], + [$this->equalTo('flash'), $this->callback(function($flash) { + return $flash instanceof Flash && empty($flash->get()); + })] + ); + + $result = $view->getTwig(); + $resultSaved = $view->getTwig(); + + $this->assertEquals($env, $result, "Twig environment should be returned"); + $this->assertEquals($env, $resultSaved, "Saved twig environment should be returned"); + } + + /** + * Test getting twig loader and environment + */ + public function testGetTwigEnvironment() + { + $view = $this->getView(); + $loader = $view->getTwigLoader(); + $env = $view->getTwigEnvironment($loader); + + $this->assertInstanceOf(Twig_Environment::class, $env); + $this->assertInstanceOf(Twig_Loader_Filesystem::class, $loader); + $this->assertEquals([getcwd()], $loader->getPaths(), "Twig loader should be configured for current dir"); + } + + /** + * Test 'view' function + * + * @dataProvider viewProvider + * @param string $tmplName Name of template to render + * @param string $tmplNameFull Name of template with extension + * @param array $context Variables to render + * @param string $charset Twig sharset + * @param string $html Rendered template + */ + public function testView($tmplName, $tmplNameFull, $context, $charset, $html) + { + $view = $this->getView(['getTwig']); + list($request, $response) = $this->getRequests(); + list($loader, $env, $tmpl) = $this->getTwigObjects(); + + $stream = $this->createMock(StreamInterface::class); + + $view->expects($this->once())->method('getTwig')->will($this->returnValue($env)); + $view->expects($this->once())->method('getResponse')->will($this->returnValue($response)); + $env->expects($this->once())->method('loadTemplate')->with($this->equalTo($tmplNameFull))->will($this->returnValue($tmpl)); + $env->expects($this->once())->method('getCharset')->will($this->returnValue($charset)); + $response->expects($this->once())->method('withHeader')->with($this->equalTo('Content-Type'), $this->equalTo('text/html; charset=' . $charset ))->will($this->returnSelf()); + $response->expects($this->once())->method('getBody')->will($this->returnValue($stream)); + $tmpl->expects($this->once())->method('render')->with($this->equalTo($context))->will($this->returnValue($html)); + $stream->expects($this->once())->method('write')->with($this->equalTo($html)); + + $result = $view->view($tmplName, $context); + + $this->assertEquals($response, $result, "Response should be returned"); + } + + /** + * Provide data for testing view method + * + * @return array + */ + public function viewProvider() + { + return [ + ['test-template', 'test-template.html.twig', ['test' => 'value'], 'test-charset', 'rendered template'], + ['test-template.html.twig', 'test-template.html.twig', ['test' => 'value'], 'test-charset', 'rendered template'], + ]; + } + + /** + * Test creating twig function + * + * @dataProvider createTwigFunctionFilterProvider + * @param string $class Twig function or filter class + * @param string $createMethod + * @param string $name Created function or filter name + * @param callable $function + */ + public function testCreateTwigFunctionFilter($class, $createMethod, $name, $function) + { + if (!$name) $this->expectException(InvalidArgumentException::class); + + $view = $this->getView(); + $result = $view->createTwigFunction($name, $function); + $callback = $result->getCallable(); + + $this->assertInstanceOf(Twig_SimpleFunction::class, $result, "Result must be an instance of 'Twig_SimpleFunction'"); + $this->assertEquals($name, $result->getName(), "Function name is not set correctly"); + + if (!$function) { + $this->assertEquals($name, $callback); + } else { + $this->assertEquals(call_user_func($function), call_user_func($callback), "Function body was not set correctly"); + } + } + + /** + * Provide data for testing creating functions and filter for twig + * + * @return array + */ + public function createTwigFunctionFilterProvider() + { + return [ + [Twig_SimpleFunction::class, 'createTwigFunction', 'test_name', function() {return 'success_call';}], + [Twig_SimpleFunction::class, 'createTwigFunction', 'test_name', null], + [Twig_SimpleFilter::class, 'createTwigFilter', 'test_name', function() {return 'success_call';}], + [Twig_SimpleFilter::class, 'createTwigFilter', 'test_name', null], + [Twig_SimpleFunction::class, 'createTwigFunction', '', function() {return 'success_call';}], + [Twig_SimpleFilter::class, 'createTwigFilter', '', function() {return 'success_call';}], + ]; + } + + /** + * Test 'setViewFunction' method + * + * @dataProvider setViewFunctionFunctionProvider + * @param string $name + * @param callable $callable + * @param string $type + * @param boolean $positive + */ + public function testSetViewFunctionFunction($name, $callable, $type, $positive) + { + $view = $this->getView(['getTwig', 'createTwigFunction', 'createTwigFilter']); + $twig = $this->createMock(Twig_Environment::class); + $function = $this->createMock(Twig_SimpleFunction::class); + + if ($positive) { + $view->expects($this->once())->method('getTwig')->will($this->returnValue($twig)); + $view->expects($this->once())->method('createTwigFunction')->with($this->equalTo($name), $this->equalTo($callable))->will($this->returnValue($function)); + $view->expects($this->never())->method('createTwigFilter'); + $twig->expects($this->once())->method('addFunction')->with($this->equalTo($function)); + } else { + $this->expectException(InvalidArgumentException::class); + } + + $result = $view->setViewFunction($name, $callable, $type); + + $this->assertEquals($view, $result, "Method should return \$this"); + } + + /** + * Provide data for testing 'setViewFunction' method when creating functions + * + * @return array + */ + public function setViewFunctionFunctionProvider() + { + return [ + ['test_name', function() {}, 'function', true], + ['test_name', function() {}, 'not_function_or_filter', false] + ]; + } + + /** + * Test 'setViewFunction' method + * + * @dataProvider setViewFunctionFilterProvider + * @param string $name + * @param callable $callable + */ + public function testSetViewFunctionFilter($name, $callable) + { + $view = $this->getView(['getTwig', 'createTwigFunction', 'createTwigFilter']); + $twig = $this->createMock(Twig_Environment::class); + $function = $this->createMock(Twig_SimpleFilter::class); + + $view->expects($this->once())->method('getTwig')->will($this->returnValue($twig)); + $view->expects($this->once())->method('createTwigFilter')->with($this->equalTo($name), $this->equalTo($callable))->will($this->returnValue($function)); + $view->expects($this->never())->method('createTwigFunction'); + $twig->expects($this->once())->method('addFilter')->with($this->equalTo($function)); + + $result = $view->setViewFunction($name, $callable, 'filter'); + + $this->assertEquals($view, $result, "Method should return \$this"); + } + + /** + * Provide data for testing 'setViewFunction' method when creating filter + * + * @return array + */ + public function setViewFunctionFilterProvider() + { + return [ + ['test_name', function() {}] + ]; + } + + /** + * Test 'setViewVariable' method + * + * @dataProvider setViewVariableProvider + */ + public function testSetViewVariable($name, $value) + { + $view = $this->getView(['getTwig']); + $twig = $this->createMock(Twig_Environment::class); + + if (!$name) { + $this->expectException(InvalidArgumentException::class); + } else { + $view->expects($this->once())->method('getTwig')->will($this->returnValue($twig)); + $twig->expects($this->once())->method('addGlobal')->with($this->equalTo($name), $this->equalTo($value)); + } + + $result = $view->setViewVariable($name, $value); + + $this->assertEquals($view, $result, "Method should return \$this"); + } + + /** + * Provide data for testing 'setViewVariable' method + * + * @return array + */ + public function setViewVariableProvider() + { + return [ + ['test_name', 'test_value'], + ['test_name', ''], + ['', 'test_value'], + ]; + } + + /** + * Test edding extension to twig + */ + public function testSetViewExtension() + { + $view = $this->getView(['getTwig']); + $twig = $this->createMock(Twig_Environment::class); + $ext = $this->createMock(Twig_ExtensionInterface::class); + + $view->expects($this->once())->method('getTwig')->will($this->returnValue($twig)); + $twig->expects($this->once())->method('addExtension')->with($this->equalTo($ext)); + + $result = $view->setViewExtension($ext); + + $this->assertEquals($view, $result, "Method should return \$this"); + } + + /** + * Get mock for testing trait + * + * @param array $methods Methods to mock + * @return Twig + */ + public function getView($methods = []) + { + return $this->getMockForTrait(Twig::class, [], '', true, true, true, $methods); + } + + /** + * Get mocks representing twig objects + * + * @return array + */ + public function getTwigObjects() + { + return [ + $this->createMock(Twig_Loader_Filesystem::class), + $this->createMock(Twig_Environment::class), + $this->createMock(Twig_Template::class) + ]; + } + + /** + * Get request and response instances + * + * @return array + */ + public function getRequests() + { + return [ + $this->createMock(ServerRequestInterface::class), + $this->createMock(ResponseInterface::class) + ]; + } +} |