ServerProtocolTest.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. <?php
  2. namespace Ratchet\Wamp;
  3. use Ratchet\Mock\Connection;
  4. use Ratchet\Mock\WampComponent as TestComponent;
  5. /**
  6. * @covers \Ratchet\Wamp\ServerProtocol
  7. * @covers \Ratchet\Wamp\WampServerInterface
  8. * @covers \Ratchet\Wamp\WampConnection
  9. */
  10. class ServerProtocolTest extends \PHPUnit_Framework_TestCase {
  11. protected $_comp;
  12. protected $_app;
  13. public function setUp() {
  14. $this->_app = new TestComponent;
  15. $this->_comp = new ServerProtocol($this->_app);
  16. }
  17. protected function newConn() {
  18. return new Connection;
  19. }
  20. public function invalidMessageProvider() {
  21. return [
  22. [0]
  23. , [3]
  24. , [4]
  25. , [8]
  26. , [9]
  27. ];
  28. }
  29. /**
  30. * @dataProvider invalidMessageProvider
  31. */
  32. public function testInvalidMessages($type) {
  33. $this->setExpectedException('\Ratchet\Wamp\Exception');
  34. $conn = $this->newConn();
  35. $this->_comp->onOpen($conn);
  36. $this->_comp->onMessage($conn, json_encode([$type]));
  37. }
  38. public function testWelcomeMessage() {
  39. $conn = $this->newConn();
  40. $this->_comp->onOpen($conn);
  41. $message = $conn->last['send'];
  42. $json = json_decode($message);
  43. $this->assertEquals(4, count($json));
  44. $this->assertEquals(0, $json[0]);
  45. $this->assertTrue(is_string($json[1]));
  46. $this->assertEquals(1, $json[2]);
  47. }
  48. public function testSubscribe() {
  49. $uri = 'http://example.com';
  50. $clientMessage = array(5, $uri);
  51. $conn = $this->newConn();
  52. $this->_comp->onOpen($conn);
  53. $this->_comp->onMessage($conn, json_encode($clientMessage));
  54. $this->assertEquals($uri, $this->_app->last['onSubscribe'][1]);
  55. }
  56. public function testUnSubscribe() {
  57. $uri = 'http://example.com/endpoint';
  58. $clientMessage = array(6, $uri);
  59. $conn = $this->newConn();
  60. $this->_comp->onOpen($conn);
  61. $this->_comp->onMessage($conn, json_encode($clientMessage));
  62. $this->assertEquals($uri, $this->_app->last['onUnSubscribe'][1]);
  63. }
  64. public function callProvider() {
  65. return [
  66. [2, 'a', 'b']
  67. , [2, ['a', 'b']]
  68. , [1, 'one']
  69. , [3, 'one', 'two', 'three']
  70. , [3, ['un', 'deux', 'trois']]
  71. , [2, 'hi', ['hello', 'world']]
  72. , [2, ['hello', 'world'], 'hi']
  73. , [2, ['hello' => 'world', 'herp' => 'derp']]
  74. ];
  75. }
  76. /**
  77. * @dataProvider callProvider
  78. */
  79. public function testCall() {
  80. $args = func_get_args();
  81. $paramNum = array_shift($args);
  82. $uri = 'http://example.com/endpoint/' . rand(1, 100);
  83. $id = uniqid('', false);
  84. $clientMessage = array_merge(array(2, $id, $uri), $args);
  85. $conn = $this->newConn();
  86. $this->_comp->onOpen($conn);
  87. $this->_comp->onMessage($conn, json_encode($clientMessage));
  88. $this->assertEquals($id, $this->_app->last['onCall'][1]);
  89. $this->assertEquals($uri, $this->_app->last['onCall'][2]);
  90. $this->assertEquals($paramNum, count($this->_app->last['onCall'][3]));
  91. }
  92. public function testPublish() {
  93. $conn = $this->newConn();
  94. $topic = 'pubsubhubbub';
  95. $event = 'Here I am, publishing data';
  96. $clientMessage = array(7, $topic, $event);
  97. $this->_comp->onOpen($conn);
  98. $this->_comp->onMessage($conn, json_encode($clientMessage));
  99. $this->assertEquals($topic, $this->_app->last['onPublish'][1]);
  100. $this->assertEquals($event, $this->_app->last['onPublish'][2]);
  101. $this->assertEquals(array(), $this->_app->last['onPublish'][3]);
  102. $this->assertEquals(array(), $this->_app->last['onPublish'][4]);
  103. }
  104. public function testPublishAndExcludeMe() {
  105. $conn = $this->newConn();
  106. $this->_comp->onOpen($conn);
  107. $this->_comp->onMessage($conn, json_encode(array(7, 'topic', 'event', true)));
  108. $this->assertEquals($conn->WAMP->sessionId, $this->_app->last['onPublish'][3][0]);
  109. }
  110. public function testPublishAndEligible() {
  111. $conn = $this->newConn();
  112. $buddy = uniqid('', false);
  113. $friend = uniqid('', false);
  114. $this->_comp->onOpen($conn);
  115. $this->_comp->onMessage($conn, json_encode(array(7, 'topic', 'event', false, array($buddy, $friend))));
  116. $this->assertEquals(array(), $this->_app->last['onPublish'][3]);
  117. $this->assertEquals(2, count($this->_app->last['onPublish'][4]));
  118. }
  119. public function eventProvider() {
  120. return array(
  121. array('http://example.com', array('one', 'two'))
  122. , array('curie', array(array('hello' => 'world', 'herp' => 'derp')))
  123. );
  124. }
  125. /**
  126. * @dataProvider eventProvider
  127. */
  128. public function testEvent($topic, $payload) {
  129. $conn = new WampConnection($this->newConn());
  130. $conn->event($topic, $payload);
  131. $eventString = $conn->last['send'];
  132. $this->assertSame(array(8, $topic, $payload), json_decode($eventString, true));
  133. }
  134. public function testOnClosePropagation() {
  135. $conn = new Connection;
  136. $this->_comp->onOpen($conn);
  137. $this->_comp->onClose($conn);
  138. $class = new \ReflectionClass('\\Ratchet\\Wamp\\WampConnection');
  139. $method = $class->getMethod('getConnection');
  140. $method->setAccessible(true);
  141. $check = $method->invokeArgs($this->_app->last['onClose'][0], array());
  142. $this->assertSame($conn, $check);
  143. }
  144. public function testOnErrorPropagation() {
  145. $conn = new Connection;
  146. $e = new \Exception('Nope');
  147. $this->_comp->onOpen($conn);
  148. $this->_comp->onError($conn, $e);
  149. $class = new \ReflectionClass('\\Ratchet\\Wamp\\WampConnection');
  150. $method = $class->getMethod('getConnection');
  151. $method->setAccessible(true);
  152. $check = $method->invokeArgs($this->_app->last['onError'][0], array());
  153. $this->assertSame($conn, $check);
  154. $this->assertSame($e, $this->_app->last['onError'][1]);
  155. }
  156. public function testPrefix() {
  157. $conn = new WampConnection($this->newConn());
  158. $this->_comp->onOpen($conn);
  159. $prefix = 'incoming';
  160. $fullURI = "http://example.com/$prefix";
  161. $method = 'call';
  162. $this->_comp->onMessage($conn, json_encode(array(1, $prefix, $fullURI)));
  163. $this->assertEquals($fullURI, $conn->WAMP->prefixes[$prefix]);
  164. $this->assertEquals("$fullURI#$method", $conn->getUri("$prefix:$method"));
  165. }
  166. public function testMessageMustBeJson() {
  167. $this->setExpectedException('\\Ratchet\\Wamp\\JsonException');
  168. $conn = new Connection;
  169. $this->_comp->onOpen($conn);
  170. $this->_comp->onMessage($conn, 'Hello World!');
  171. }
  172. public function testGetSubProtocolsReturnsArray() {
  173. $this->assertTrue(is_array($this->_comp->getSubProtocols()));
  174. }
  175. public function testGetSubProtocolsGetFromApp() {
  176. $this->_app->protocols = array('hello', 'world');
  177. $this->assertGreaterThanOrEqual(3, count($this->_comp->getSubProtocols()));
  178. }
  179. public function testWampOnMessageApp() {
  180. $app = $this->getMock('\\Ratchet\\Wamp\\WampServerInterface');
  181. $wamp = new ServerProtocol($app);
  182. $this->assertContains('wamp', $wamp->getSubProtocols());
  183. }
  184. public function badFormatProvider() {
  185. return array(
  186. array(json_encode(true))
  187. , array('{"valid":"json", "invalid": "message"}')
  188. , array('{"0": "fail", "hello": "world"}')
  189. );
  190. }
  191. /**
  192. * @dataProvider badFormatProvider
  193. */
  194. public function testValidJsonButInvalidProtocol($message) {
  195. $this->setExpectedException('\Ratchet\Wamp\Exception');
  196. $conn = $this->newConn();
  197. $this->_comp->onOpen($conn);
  198. $this->_comp->onMessage($conn, $message);
  199. }
  200. public function testBadClientInputFromNonStringTopic() {
  201. $this->setExpectedException('\Ratchet\Wamp\Exception');
  202. $conn = new WampConnection($this->newConn());
  203. $this->_comp->onOpen($conn);
  204. $this->_comp->onMessage($conn, json_encode([5, ['hells', 'nope']]));
  205. }
  206. public function testBadPrefixWithNonStringTopic() {
  207. $this->setExpectedException('\Ratchet\Wamp\Exception');
  208. $conn = new WampConnection($this->newConn());
  209. $this->_comp->onOpen($conn);
  210. $this->_comp->onMessage($conn, json_encode([1, ['hells', 'nope'], ['bad', 'input']]));
  211. }
  212. public function testBadPublishWithNonStringTopic() {
  213. $this->setExpectedException('\Ratchet\Wamp\Exception');
  214. $conn = new WampConnection($this->newConn());
  215. $this->_comp->onOpen($conn);
  216. $this->_comp->onMessage($conn, json_encode([7, ['bad', 'input'], 'Hider']));
  217. }
  218. }