RouterTest.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. namespace Ratchet\Http;
  3. use Ratchet\WebSocket\WsServerInterface;
  4. use Symfony\Component\Routing\Exception\ResourceNotFoundException;
  5. use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
  6. use Symfony\Component\Routing\RequestContext;
  7. use Symfony\Component\Routing\RouteCollection;
  8. use Symfony\Component\Routing\Matcher\UrlMatcher;
  9. /**
  10. * @covers Ratchet\Http\Router
  11. */
  12. class RouterTest extends \PHPUnit_Framework_TestCase {
  13. protected $_router;
  14. protected $_matcher;
  15. protected $_conn;
  16. protected $_uri;
  17. protected $_req;
  18. public function setUp() {
  19. $this->_conn = $this->getMock('\Ratchet\ConnectionInterface');
  20. $this->_uri = $this->getMock('Psr\Http\Message\UriInterface');
  21. $this->_req = $this->getMock('\Psr\Http\Message\RequestInterface');
  22. $this->_req
  23. ->expects($this->any())
  24. ->method('getUri')
  25. ->will($this->returnValue($this->_uri));
  26. $this->_matcher = $this->getMock('Symfony\Component\Routing\Matcher\UrlMatcherInterface');
  27. $this->_matcher
  28. ->expects($this->any())
  29. ->method('getContext')
  30. ->will($this->returnValue($this->getMock('Symfony\Component\Routing\RequestContext')));
  31. $this->_router = new Router($this->_matcher);
  32. $this->_uri->expects($this->any())->method('getPath')->will($this->returnValue('ws://doesnt.matter/'));
  33. $this->_uri->expects($this->any())->method('withQuery')->with($this->callback(function($val) {
  34. $this->setResult($val);
  35. return true;
  36. }))->will($this->returnSelf());
  37. $this->_uri->expects($this->any())->method('getQuery')->will($this->returnCallback([$this, 'getResult']));
  38. $this->_req->expects($this->any())->method('withUri')->will($this->returnSelf());
  39. }
  40. public function testFourOhFour() {
  41. $this->_conn->expects($this->once())->method('close');
  42. $nope = new ResourceNotFoundException;
  43. $this->_matcher->expects($this->any())->method('match')->will($this->throwException($nope));
  44. $this->_router->onOpen($this->_conn, $this->_req);
  45. }
  46. public function testNullRequest() {
  47. $this->setExpectedException('\UnexpectedValueException');
  48. $this->_router->onOpen($this->_conn);
  49. }
  50. public function testControllerIsMessageComponentInterface() {
  51. $this->setExpectedException('\UnexpectedValueException');
  52. $this->_matcher->expects($this->any())->method('match')->will($this->returnValue(array('_controller' => new \StdClass)));
  53. $this->_router->onOpen($this->_conn, $this->_req);
  54. }
  55. public function testControllerOnOpen() {
  56. $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
  57. $this->_matcher->expects($this->any())->method('match')->will($this->returnValue(array('_controller' => $controller)));
  58. $this->_router->onOpen($this->_conn, $this->_req);
  59. $expectedConn = new \PHPUnit_Framework_Constraint_IsInstanceOf('\Ratchet\ConnectionInterface');
  60. $controller->expects($this->once())->method('onOpen')->with($expectedConn, $this->_req);
  61. $this->_matcher->expects($this->any())->method('match')->will($this->returnValue(array('_controller' => $controller)));
  62. $this->_router->onOpen($this->_conn, $this->_req);
  63. }
  64. public function testControllerOnMessageBubbles() {
  65. $message = "The greatest trick the Devil ever pulled was convincing the world he didn't exist";
  66. $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
  67. $controller->expects($this->once())->method('onMessage')->with($this->_conn, $message);
  68. $this->_conn->controller = $controller;
  69. $this->_router->onMessage($this->_conn, $message);
  70. }
  71. public function testControllerOnCloseBubbles() {
  72. $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
  73. $controller->expects($this->once())->method('onClose')->with($this->_conn);
  74. $this->_conn->controller = $controller;
  75. $this->_router->onClose($this->_conn);
  76. }
  77. public function testControllerOnErrorBubbles() {
  78. $e= new \Exception('One cannot be betrayed if one has no exceptions');
  79. $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
  80. $controller->expects($this->once())->method('onError')->with($this->_conn, $e);
  81. $this->_conn->controller = $controller;
  82. $this->_router->onError($this->_conn, $e);
  83. }
  84. public function testRouterGeneratesRouteParameters() {
  85. /** @var $controller WsServerInterface */
  86. $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
  87. /** @var $matcher UrlMatcherInterface */
  88. $this->_matcher->expects($this->any())->method('match')->will(
  89. $this->returnValue(['_controller' => $controller, 'foo' => 'bar', 'baz' => 'qux'])
  90. );
  91. $conn = $this->getMock('Ratchet\Mock\Connection');
  92. $router = new Router($this->_matcher);
  93. $router->onOpen($conn, $this->_req);
  94. $this->assertEquals('foo=bar&baz=qux', $this->_req->getUri()->getQuery());
  95. }
  96. public function testQueryParams() {
  97. $controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
  98. $this->_matcher->expects($this->any())->method('match')->will(
  99. $this->returnValue(['_controller' => $controller, 'foo' => 'bar', 'baz' => 'qux'])
  100. );
  101. $conn = $this->getMock('Ratchet\Mock\Connection');
  102. $request = $this->getMock('Psr\Http\Message\RequestInterface');
  103. $uri = new \GuzzleHttp\Psr7\Uri('ws://doesnt.matter/endpoint?hello=world&foo=nope');
  104. $request->expects($this->any())->method('getUri')->will($this->returnCallback(function() use (&$uri) {
  105. return $uri;
  106. }));
  107. $request->expects($this->any())->method('withUri')->with($this->callback(function($url) use (&$uri) {
  108. $uri = $url;
  109. return true;
  110. }))->will($this->returnSelf());
  111. $router = new Router($this->_matcher);
  112. $router->onOpen($conn, $request);
  113. $this->assertEquals('foo=nope&baz=qux&hello=world', $request->getUri()->getQuery());
  114. $this->assertEquals('ws', $request->getUri()->getScheme());
  115. $this->assertEquals('doesnt.matter', $request->getUri()->getHost());
  116. }
  117. public function testImpatientClientOverflow() {
  118. $this->_conn->expects($this->once())->method('close');
  119. $header = "GET /nope HTTP/1.1
  120. Upgrade: websocket
  121. Connection: upgrade
  122. Host: localhost
  123. Origin: http://localhost
  124. Sec-WebSocket-Version: 13\r\n\r\n";
  125. $app = new HttpServer(new Router(new UrlMatcher(new RouteCollection, new RequestContext)));
  126. $app->onOpen($this->_conn);
  127. $app->onMessage($this->_conn, $header);
  128. $app->onMessage($this->_conn, 'Silly body');
  129. }
  130. }