diff options
author | Arnold Daniels <arnold@jasny.net> | 2016-11-18 18:28:24 +0100 |
---|---|---|
committer | Arnold Daniels <arnold@jasny.net> | 2016-11-18 18:28:24 +0100 |
commit | 43c6d835943b322c036e9ee47800d694cb6bb5de (patch) | |
tree | f56809890b4e65c2f4790fbd8be9593a3538a72c /tests | |
parent | 934b380f473b4e85e807f07d6bf516f4e227e112 (diff) | |
download | controller-43c6d835943b322c036e9ee47800d694cb6bb5de.zip controller-43c6d835943b322c036e9ee47800d694cb6bb5de.tar.gz controller-43c6d835943b322c036e9ee47800d694cb6bb5de.tar.bz2 |
Refactored CheckRequest and CheckResponse traits
WIP Controller\Output
Restructuring the tests (one test per trait)
Diffstat (limited to 'tests')
-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 (renamed from tests/FlashTest.php) | 0 | ||||
-rw-r--r-- | tests/Controller/SessionTest.php | 750 | ||||
-rw-r--r-- | tests/Controller/View/TwigTest.php (renamed from tests/View/TwigTest.php) | 0 | ||||
-rw-r--r-- | tests/ControllerTest.php | 723 | ||||
-rw-r--r-- | tests/bootstrap.php | 4 | ||||
-rw-r--r-- | tests/support/RouteActionController.php | 13 | ||||
-rw-r--r-- | tests/support/SessionController.php | 13 | ||||
-rw-r--r-- | tests/support/TestController.php | 50 | ||||
-rw-r--r-- | tests/support/TestHelper.php | 27 |
13 files changed, 1454 insertions, 768 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/FlashTest.php b/tests/Controller/Session/FlashTest.php index c17c446..c17c446 100644 --- a/tests/FlashTest.php +++ b/tests/Controller/Session/FlashTest.php 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/View/TwigTest.php b/tests/Controller/View/TwigTest.php index 662681d..662681d 100644 --- a/tests/View/TwigTest.php +++ b/tests/Controller/View/TwigTest.php diff --git a/tests/ControllerTest.php b/tests/ControllerTest.php index b6a6b2d..3e3b39c 100644 --- a/tests/ControllerTest.php +++ b/tests/ControllerTest.php @@ -1,32 +1,19 @@ <?php +namespace Jasny; + 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 */ -class ControllerTest extends PHPUnit_Framework_TestCase +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(); - } - + use TestHelper; + /** * Test running controller */ @@ -40,7 +27,7 @@ class ControllerTest extends PHPUnit_Framework_TestCase $finalResponse = $this->createMock(ResponseInterface::class); $controller->expects($this->once())->method('run') - ->willReturnCallback(Closure::bind(function() use ($test, $request, $response, $finalResponse) { + ->willReturnCallback(\Closure::bind(function() use ($test, $request, $response, $finalResponse) { $test->assertSame($request, $this->getRequest()); $test->assertSame($response, $this->getResponse()); @@ -51,700 +38,4 @@ class ControllerTest extends PHPUnit_Framework_TestCase $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/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..7648e13 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,4 @@ +<?php + +$loader = require __DIR__ . '/../vendor/autoload.php'; +$loader->addPsr4('Jasny\\Controller\\', __DIR__ . '/support'); diff --git a/tests/support/RouteActionController.php b/tests/support/RouteActionController.php new file mode 100644 index 0000000..66625a9 --- /dev/null +++ b/tests/support/RouteActionController.php @@ -0,0 +1,13 @@ +<?php + +namespace Jasny\Controller; + +use Jasny\Controller; + +/** + * Class for testing 'RouteAction' trait + */ +class RouteActionController extends Controller +{ + use Controller\RouteAction; +} diff --git a/tests/support/SessionController.php b/tests/support/SessionController.php new file mode 100644 index 0000000..6758419 --- /dev/null +++ b/tests/support/SessionController.php @@ -0,0 +1,13 @@ +<?php + +namespace Jasny\Controller; + +use Jasny\Controller; + +/** + * Class for testing 'Session' trait + */ +abstract class SessionController extends Controller +{ + use Controller\Session; +} diff --git a/tests/support/TestController.php b/tests/support/TestController.php deleted file mode 100644 index e0bdb7b..0000000 --- a/tests/support/TestController.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php - -use Jasny\Controller; -use Jasny\Controller\RouteAction; -use Psr\Http\Message\ServerRequestInterface; -use Psr\Http\Message\ResponseInterface; - -/** - * Class for testing 'RouteAction' trait - */ -class TestController extends Controller -{ - use RouteAction; - - /** - * Test action for executing router - * - * @param mixed $param1 - * @param mixed $param2 - * @return ResponseInterface - */ - public function testRunAction($param1, $param2 = 'defaultValue') - { - $response = $this->getResponse(); - - $response->actionCalled = true; - $response->param1 = $param1; - $response->param2 = $param2; - - return $response; - } - - /** - * Test action for executing router - * - * @param mixed $param1 - * @param mixed $param2 - * @return ResponseInterface - */ - public function defaultAction($param1, $param2 = 'defaultValue') - { - $response = $this->getResponse(); - - $response->defaultActionCalled = true; - $response->param1 = $param1; - $response->param2 = $param2; - - return $response; - } -} diff --git a/tests/support/TestHelper.php b/tests/support/TestHelper.php new file mode 100644 index 0000000..01347f4 --- /dev/null +++ b/tests/support/TestHelper.php @@ -0,0 +1,27 @@ +<?php + +namespace Jasny\Controller; + +use Jasny\Controller; + +/** + * Additional test methods + */ +trait TestHelper +{ + /** + * Get mock for controller + * + * @param array $methods Methods to mock + * @return Controller|\PHPUnit_Framework_MockObject_MockObject + */ + public function getController($methods = []) + { + $builder = $this->getMockBuilder(Controller::class)->disableOriginalConstructor(); + if ($methods) { + $builder->setMethods($methods); + } + + return $builder->getMockForAbstractClass(); + } +} |