init Abgabe
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
use Ratchet\ConnectionInterface;
|
||||
|
||||
require dirname(dirname(dirname(__DIR__))) . '/vendor/autoload.php';
|
||||
|
||||
class BinaryEcho implements \Ratchet\WebSocket\MessageComponentInterface {
|
||||
public function onMessage(ConnectionInterface $from, \Ratchet\RFC6455\Messaging\MessageInterface $msg) {
|
||||
$from->send($msg);
|
||||
}
|
||||
|
||||
public function onOpen(ConnectionInterface $conn) {
|
||||
}
|
||||
|
||||
public function onClose(ConnectionInterface $conn) {
|
||||
}
|
||||
|
||||
public function onError(ConnectionInterface $conn, \Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
$port = $argc > 1 ? $argv[1] : 8000;
|
||||
$impl = sprintf('React\EventLoop\%sLoop', $argc > 2 ? $argv[2] : 'StreamSelect');
|
||||
|
||||
$loop = new $impl;
|
||||
$sock = new React\Socket\Server('0.0.0.0:' . $port, $loop);
|
||||
|
||||
$wsServer = new Ratchet\WebSocket\WsServer(new BinaryEcho);
|
||||
// This is enabled to test https://github.com/ratchetphp/Ratchet/issues/430
|
||||
// The time is left at 10 minutes so that it will not try to every ping anything
|
||||
// This causes the Ratchet server to crash on test 2.7
|
||||
$wsServer->enableKeepAlive($loop, 600);
|
||||
|
||||
$app = new Ratchet\Http\HttpServer($wsServer);
|
||||
|
||||
$server = new Ratchet\Server\IoServer($app, $sock, $loop);
|
||||
$server->run();
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"options": {"failByDrop": false}
|
||||
, "outdir": "reports/ab"
|
||||
|
||||
, "servers": [
|
||||
{"agent": "Ratchet/0.4 libevent", "url": "ws://localhost:8001", "options": {"version": 18}}
|
||||
, {"agent": "Ratchet/0.4 libev", "url": "ws://localhost:8004", "options": {"version": 18}}
|
||||
, {"agent": "Ratchet/0.4 streams", "url": "ws://localhost:8002", "options": {"version": 18}}
|
||||
, {"agent": "AutobahnTestSuite/0.5.9", "url": "ws://localhost:8000", "options": {"version": 18}}
|
||||
]
|
||||
|
||||
, "cases": ["*"]
|
||||
, "exclude-cases": []
|
||||
, "exclude-agent-cases": {}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"options": {"failByDrop": false}
|
||||
, "outdir": "reports/profile"
|
||||
|
||||
, "servers": [
|
||||
{"agent": "Ratchet", "url": "ws://localhost:8000", "options": {"version": 18}}
|
||||
]
|
||||
|
||||
, "cases": ["9.7.4"]
|
||||
, "exclude-cases": ["1.2.*", "2.3", "2.4", "2.6", "9.2.*", "9.4.*", "9.6.*", "9.8.*"]
|
||||
, "exclude-agent-cases": {}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"options": {"failByDrop": false}
|
||||
, "outdir": "reports/rfc"
|
||||
|
||||
, "servers": [
|
||||
{"agent": "Ratchet", "url": "ws://localhost:8000", "options": {"version": 18}}
|
||||
]
|
||||
|
||||
, "cases": ["*"]
|
||||
, "exclude-cases": []
|
||||
, "exclude-agent-cases": {}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
$loader = require __DIR__ . '/../vendor/autoload.php';
|
||||
$loader->addPsr4('Ratchet\\', __DIR__ . '/helpers/Ratchet');
|
||||
Vendored
+50
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
namespace Ratchet;
|
||||
|
||||
abstract class AbstractMessageComponentTestCase extends \PHPUnit_Framework_TestCase {
|
||||
protected $_app;
|
||||
protected $_serv;
|
||||
protected $_conn;
|
||||
|
||||
abstract public function getConnectionClassString();
|
||||
abstract public function getDecoratorClassString();
|
||||
abstract public function getComponentClassString();
|
||||
|
||||
public function setUp() {
|
||||
$this->_app = $this->getMock($this->getComponentClassString());
|
||||
$decorator = $this->getDecoratorClassString();
|
||||
$this->_serv = new $decorator($this->_app);
|
||||
$this->_conn = $this->getMock('\Ratchet\ConnectionInterface');
|
||||
|
||||
$this->doOpen($this->_conn);
|
||||
}
|
||||
|
||||
protected function doOpen($conn) {
|
||||
$this->_serv->onOpen($conn);
|
||||
}
|
||||
|
||||
public function isExpectedConnection() {
|
||||
return new \PHPUnit_Framework_Constraint_IsInstanceOf($this->getConnectionClassString());
|
||||
}
|
||||
|
||||
public function testOpen() {
|
||||
$this->_app->expects($this->once())->method('onOpen')->with($this->isExpectedConnection());
|
||||
$this->doOpen($this->getMock('\Ratchet\ConnectionInterface'));
|
||||
}
|
||||
|
||||
public function testOnClose() {
|
||||
$this->_app->expects($this->once())->method('onClose')->with($this->isExpectedConnection());
|
||||
$this->_serv->onClose($this->_conn);
|
||||
}
|
||||
|
||||
public function testOnError() {
|
||||
$e = new \Exception('Whoops!');
|
||||
$this->_app->expects($this->once())->method('onError')->with($this->isExpectedConnection(), $e);
|
||||
$this->_serv->onError($this->_conn, $e);
|
||||
}
|
||||
|
||||
public function passthroughMessageTest($value) {
|
||||
$this->_app->expects($this->once())->method('onMessage')->with($this->isExpectedConnection(), $value);
|
||||
$this->_serv->onMessage($this->_conn, $value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace Ratchet\Mock;
|
||||
use Ratchet\MessageComponentInterface;
|
||||
use Ratchet\WebSocket\WsServerInterface;
|
||||
use Ratchet\ConnectionInterface;
|
||||
|
||||
class Component implements MessageComponentInterface, WsServerInterface {
|
||||
public $last = array();
|
||||
|
||||
public $protocols = array();
|
||||
|
||||
public function __construct(ComponentInterface $app = null) {
|
||||
$this->last[__FUNCTION__] = func_get_args();
|
||||
}
|
||||
|
||||
public function onOpen(ConnectionInterface $conn) {
|
||||
$this->last[__FUNCTION__] = func_get_args();
|
||||
}
|
||||
|
||||
public function onMessage(ConnectionInterface $from, $msg) {
|
||||
$this->last[__FUNCTION__] = func_get_args();
|
||||
}
|
||||
|
||||
public function onClose(ConnectionInterface $conn) {
|
||||
$this->last[__FUNCTION__] = func_get_args();
|
||||
}
|
||||
|
||||
public function onError(ConnectionInterface $conn, \Exception $e) {
|
||||
$this->last[__FUNCTION__] = func_get_args();
|
||||
}
|
||||
|
||||
public function getSubProtocols() {
|
||||
return $this->protocols;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
namespace Ratchet\Mock;
|
||||
use Ratchet\ConnectionInterface;
|
||||
|
||||
class Connection implements ConnectionInterface {
|
||||
public $last = array(
|
||||
'send' => ''
|
||||
, 'close' => false
|
||||
);
|
||||
|
||||
public $remoteAddress = '127.0.0.1';
|
||||
|
||||
public function send($data) {
|
||||
$this->last[__FUNCTION__] = $data;
|
||||
}
|
||||
|
||||
public function close() {
|
||||
$this->last[__FUNCTION__] = true;
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace Ratchet\Mock;
|
||||
use Ratchet\AbstractConnectionDecorator;
|
||||
|
||||
class ConnectionDecorator extends AbstractConnectionDecorator {
|
||||
public $last = array(
|
||||
'write' => ''
|
||||
, 'end' => false
|
||||
);
|
||||
|
||||
public function send($data) {
|
||||
$this->last[__FUNCTION__] = $data;
|
||||
|
||||
$this->getConnection()->send($data);
|
||||
}
|
||||
|
||||
public function close() {
|
||||
$this->last[__FUNCTION__] = true;
|
||||
|
||||
$this->getConnection()->close();
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
namespace Ratchet\Mock;
|
||||
use Ratchet\Wamp\WampServerInterface;
|
||||
use Ratchet\WebSocket\WsServerInterface;
|
||||
use Ratchet\ConnectionInterface;
|
||||
|
||||
class WampComponent implements WampServerInterface, WsServerInterface {
|
||||
public $last = array();
|
||||
|
||||
public $protocols = array();
|
||||
|
||||
public function getSubProtocols() {
|
||||
return $this->protocols;
|
||||
}
|
||||
|
||||
public function onCall(ConnectionInterface $conn, $id, $procURI, array $params) {
|
||||
$this->last[__FUNCTION__] = func_get_args();
|
||||
}
|
||||
|
||||
public function onSubscribe(ConnectionInterface $conn, $topic) {
|
||||
$this->last[__FUNCTION__] = func_get_args();
|
||||
}
|
||||
|
||||
public function onUnSubscribe(ConnectionInterface $conn, $topic) {
|
||||
$this->last[__FUNCTION__] = func_get_args();
|
||||
}
|
||||
|
||||
public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) {
|
||||
$this->last[__FUNCTION__] = func_get_args();
|
||||
}
|
||||
|
||||
public function onOpen(ConnectionInterface $conn) {
|
||||
$this->last[__FUNCTION__] = func_get_args();
|
||||
}
|
||||
|
||||
public function onClose(ConnectionInterface $conn) {
|
||||
$this->last[__FUNCTION__] = func_get_args();
|
||||
}
|
||||
|
||||
public function onError(ConnectionInterface $conn, \Exception $e) {
|
||||
$this->last[__FUNCTION__] = func_get_args();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
namespace Ratchet;
|
||||
use Ratchet\ConnectionInterface;
|
||||
use Ratchet\MessageComponentInterface;
|
||||
use Ratchet\WebSocket\WsServerInterface;
|
||||
use Ratchet\Wamp\WampServerInterface;
|
||||
|
||||
class NullComponent implements MessageComponentInterface, WsServerInterface, WampServerInterface {
|
||||
public function onOpen(ConnectionInterface $conn) {}
|
||||
|
||||
public function onMessage(ConnectionInterface $conn, $msg) {}
|
||||
|
||||
public function onClose(ConnectionInterface $conn) {}
|
||||
|
||||
public function onError(ConnectionInterface $conn, \Exception $e) {}
|
||||
|
||||
public function onCall(ConnectionInterface $conn, $id, $topic, array $params) {}
|
||||
|
||||
public function onSubscribe(ConnectionInterface $conn, $topic) {}
|
||||
|
||||
public function onUnSubscribe(ConnectionInterface $conn, $topic) {}
|
||||
|
||||
public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude = array(), array $eligible = array()) {}
|
||||
|
||||
public function getSubProtocols() {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace Ratchet\Wamp\Stub;
|
||||
use Ratchet\WebSocket\WsServerInterface;
|
||||
use Ratchet\Wamp\WampServerInterface;
|
||||
|
||||
interface WsWampServerInterface extends WsServerInterface, WampServerInterface {
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace Ratchet\WebSocket\Stub;
|
||||
use Ratchet\MessageComponentInterface;
|
||||
use Ratchet\WebSocket\WsServerInterface;
|
||||
|
||||
interface WsMessageComponentInterface extends MessageComponentInterface, WsServerInterface {
|
||||
}
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
namespace Ratchet;
|
||||
use Ratchet\Mock\ConnectionDecorator;
|
||||
|
||||
/**
|
||||
* @covers Ratchet\AbstractConnectionDecorator
|
||||
* @covers Ratchet\ConnectionInterface
|
||||
*/
|
||||
class AbstractConnectionDecoratorTest extends \PHPUnit_Framework_TestCase {
|
||||
protected $mock;
|
||||
protected $l1;
|
||||
protected $l2;
|
||||
|
||||
public function setUp() {
|
||||
$this->mock = $this->getMock('\Ratchet\ConnectionInterface');
|
||||
$this->l1 = new ConnectionDecorator($this->mock);
|
||||
$this->l2 = new ConnectionDecorator($this->l1);
|
||||
}
|
||||
|
||||
public function testGet() {
|
||||
$var = 'hello';
|
||||
$val = 'world';
|
||||
|
||||
$this->mock->$var = $val;
|
||||
|
||||
$this->assertEquals($val, $this->l1->$var);
|
||||
$this->assertEquals($val, $this->l2->$var);
|
||||
}
|
||||
|
||||
public function testSet() {
|
||||
$var = 'Chris';
|
||||
$val = 'Boden';
|
||||
|
||||
$this->l1->$var = $val;
|
||||
|
||||
$this->assertEquals($val, $this->mock->$var);
|
||||
}
|
||||
|
||||
public function testSetLevel2() {
|
||||
$var = 'Try';
|
||||
$val = 'Again';
|
||||
|
||||
$this->l2->$var = $val;
|
||||
|
||||
$this->assertEquals($val, $this->mock->$var);
|
||||
}
|
||||
|
||||
public function testIsSetTrue() {
|
||||
$var = 'PHP';
|
||||
$val = 'Ratchet';
|
||||
|
||||
$this->mock->$var = $val;
|
||||
|
||||
$this->assertTrue(isset($this->l1->$var));
|
||||
$this->assertTrue(isset($this->l2->$var));
|
||||
}
|
||||
|
||||
public function testIsSetFalse() {
|
||||
$var = 'herp';
|
||||
$val = 'derp';
|
||||
|
||||
$this->assertFalse(isset($this->l1->$var));
|
||||
$this->assertFalse(isset($this->l2->$var));
|
||||
}
|
||||
|
||||
public function testUnset() {
|
||||
$var = 'Flying';
|
||||
$val = 'Monkey';
|
||||
|
||||
$this->mock->$var = $val;
|
||||
unset($this->l1->$var);
|
||||
|
||||
$this->assertFalse(isset($this->mock->$var));
|
||||
}
|
||||
|
||||
public function testUnsetLevel2() {
|
||||
$var = 'Flying';
|
||||
$val = 'Monkey';
|
||||
|
||||
$this->mock->$var = $val;
|
||||
unset($this->l2->$var);
|
||||
|
||||
$this->assertFalse(isset($this->mock->$var));
|
||||
}
|
||||
|
||||
public function testGetConnection() {
|
||||
$class = new \ReflectionClass('\\Ratchet\\AbstractConnectionDecorator');
|
||||
$method = $class->getMethod('getConnection');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$conn = $method->invokeArgs($this->l1, array());
|
||||
|
||||
$this->assertSame($this->mock, $conn);
|
||||
}
|
||||
|
||||
public function testGetConnectionLevel2() {
|
||||
$class = new \ReflectionClass('\\Ratchet\\AbstractConnectionDecorator');
|
||||
$method = $class->getMethod('getConnection');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$conn = $method->invokeArgs($this->l2, array());
|
||||
|
||||
$this->assertSame($this->l1, $conn);
|
||||
}
|
||||
|
||||
public function testWrapperCanStoreSelfInDecorator() {
|
||||
$this->mock->decorator = $this->l1;
|
||||
|
||||
$this->assertSame($this->l1, $this->l2->decorator);
|
||||
}
|
||||
|
||||
public function testDecoratorRecursion() {
|
||||
$this->mock->decorator = new \stdClass;
|
||||
$this->mock->decorator->conn = $this->l1;
|
||||
|
||||
$this->assertSame($this->l1, $this->mock->decorator->conn);
|
||||
$this->assertSame($this->l1, $this->l1->decorator->conn);
|
||||
$this->assertSame($this->l1, $this->l2->decorator->conn);
|
||||
}
|
||||
|
||||
public function testDecoratorRecursionLevel2() {
|
||||
$this->mock->decorator = new \stdClass;
|
||||
$this->mock->decorator->conn = $this->l2;
|
||||
|
||||
$this->assertSame($this->l2, $this->mock->decorator->conn);
|
||||
$this->assertSame($this->l2, $this->l1->decorator->conn);
|
||||
$this->assertSame($this->l2, $this->l2->decorator->conn);
|
||||
|
||||
// just for fun
|
||||
$this->assertSame($this->l2, $this->l2->decorator->conn->decorator->conn->decorator->conn);
|
||||
}
|
||||
|
||||
public function testWarningGettingNothing() {
|
||||
$this->setExpectedException('PHPUnit_Framework_Error');
|
||||
$var = $this->mock->nonExistant;
|
||||
}
|
||||
|
||||
public function testWarningGettingNothingLevel1() {
|
||||
$this->setExpectedException('PHPUnit_Framework_Error');
|
||||
$var = $this->l1->nonExistant;
|
||||
}
|
||||
|
||||
public function testWarningGettingNothingLevel2() {
|
||||
$this->setExpectedException('PHPUnit_Framework_Error');
|
||||
$var = $this->l2->nonExistant;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
namespace Ratchet\Http;
|
||||
|
||||
/**
|
||||
* @covers Ratchet\Http\HttpRequestParser
|
||||
*/
|
||||
class HttpRequestParserTest extends \PHPUnit_Framework_TestCase {
|
||||
protected $parser;
|
||||
|
||||
public function setUp() {
|
||||
$this->parser = new HttpRequestParser;
|
||||
}
|
||||
|
||||
public function headersProvider() {
|
||||
return array(
|
||||
array(false, "GET / HTTP/1.1\r\nHost: socketo.me\r\n")
|
||||
, array(true, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\n")
|
||||
, array(true, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\n1")
|
||||
, array(true, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\nHixie✖")
|
||||
, array(true, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\nHixie✖\r\n\r\n")
|
||||
, array(true, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\nHixie\r\n")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider headersProvider
|
||||
*/
|
||||
public function testIsEom($expected, $message) {
|
||||
$this->assertEquals($expected, $this->parser->isEom($message));
|
||||
}
|
||||
|
||||
public function testBufferOverflowResponse() {
|
||||
$conn = $this->getMock('\Ratchet\ConnectionInterface');
|
||||
|
||||
$this->parser->maxSize = 20;
|
||||
|
||||
$this->assertNull($this->parser->onMessage($conn, "GET / HTTP/1.1\r\n"));
|
||||
|
||||
$this->setExpectedException('OverflowException');
|
||||
|
||||
$this->parser->onMessage($conn, "Header-Is: Too Big");
|
||||
}
|
||||
|
||||
public function testReturnTypeIsRequest() {
|
||||
$conn = $this->getMock('\Ratchet\ConnectionInterface');
|
||||
$return = $this->parser->onMessage($conn, "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\n");
|
||||
|
||||
$this->assertInstanceOf('\Psr\Http\Message\RequestInterface', $return);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
namespace Ratchet\Http;
|
||||
use Ratchet\AbstractMessageComponentTestCase;
|
||||
|
||||
/**
|
||||
* @covers Ratchet\Http\HttpServer
|
||||
*/
|
||||
class HttpServerTest extends AbstractMessageComponentTestCase {
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->_conn->httpHeadersReceived = true;
|
||||
}
|
||||
|
||||
public function getConnectionClassString() {
|
||||
return '\Ratchet\ConnectionInterface';
|
||||
}
|
||||
|
||||
public function getDecoratorClassString() {
|
||||
return '\Ratchet\Http\HttpServer';
|
||||
}
|
||||
|
||||
public function getComponentClassString() {
|
||||
return '\Ratchet\Http\HttpServerInterface';
|
||||
}
|
||||
|
||||
public function testOpen() {
|
||||
$headers = "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\n";
|
||||
|
||||
$this->_conn->httpHeadersReceived = false;
|
||||
$this->_app->expects($this->once())->method('onOpen')->with($this->isExpectedConnection());
|
||||
$this->_serv->onMessage($this->_conn, $headers);
|
||||
}
|
||||
|
||||
public function testOnMessageAfterHeaders() {
|
||||
$headers = "GET / HTTP/1.1\r\nHost: socketo.me\r\n\r\n";
|
||||
$this->_conn->httpHeadersReceived = false;
|
||||
$this->_serv->onMessage($this->_conn, $headers);
|
||||
|
||||
$message = "Hello World!";
|
||||
$this->_app->expects($this->once())->method('onMessage')->with($this->isExpectedConnection(), $message);
|
||||
$this->_serv->onMessage($this->_conn, $message);
|
||||
}
|
||||
|
||||
public function testBufferOverflow() {
|
||||
$this->_conn->expects($this->once())->method('close');
|
||||
$this->_conn->httpHeadersReceived = false;
|
||||
|
||||
$this->_serv->onMessage($this->_conn, str_repeat('a', 5000));
|
||||
}
|
||||
|
||||
public function testCloseIfNotEstablished() {
|
||||
$this->_conn->httpHeadersReceived = false;
|
||||
$this->_conn->expects($this->once())->method('close');
|
||||
$this->_serv->onError($this->_conn, new \Exception('Whoops!'));
|
||||
}
|
||||
|
||||
public function testBufferHeaders() {
|
||||
$this->_conn->httpHeadersReceived = false;
|
||||
$this->_app->expects($this->never())->method('onOpen');
|
||||
$this->_app->expects($this->never())->method('onMessage');
|
||||
|
||||
$this->_serv->onMessage($this->_conn, "GET / HTTP/1.1");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace Ratchet\Http;
|
||||
use Ratchet\AbstractMessageComponentTestCase;
|
||||
|
||||
/**
|
||||
* @covers Ratchet\Http\OriginCheck
|
||||
*/
|
||||
class OriginCheckTest extends AbstractMessageComponentTestCase {
|
||||
protected $_reqStub;
|
||||
|
||||
public function setUp() {
|
||||
$this->_reqStub = $this->getMock('Psr\Http\Message\RequestInterface');
|
||||
$this->_reqStub->expects($this->any())->method('getHeader')->will($this->returnValue(['localhost']));
|
||||
|
||||
parent::setUp();
|
||||
|
||||
$this->_serv->allowedOrigins[] = 'localhost';
|
||||
}
|
||||
|
||||
protected function doOpen($conn) {
|
||||
$this->_serv->onOpen($conn, $this->_reqStub);
|
||||
}
|
||||
|
||||
public function getConnectionClassString() {
|
||||
return '\Ratchet\ConnectionInterface';
|
||||
}
|
||||
|
||||
public function getDecoratorClassString() {
|
||||
return '\Ratchet\Http\OriginCheck';
|
||||
}
|
||||
|
||||
public function getComponentClassString() {
|
||||
return '\Ratchet\Http\HttpServerInterface';
|
||||
}
|
||||
|
||||
public function testCloseOnNonMatchingOrigin() {
|
||||
$this->_serv->allowedOrigins = ['socketo.me'];
|
||||
$this->_conn->expects($this->once())->method('close');
|
||||
|
||||
$this->_serv->onOpen($this->_conn, $this->_reqStub);
|
||||
}
|
||||
|
||||
public function testOnMessage() {
|
||||
$this->passthroughMessageTest('Hello World!');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
namespace Ratchet\Http;
|
||||
use Ratchet\WebSocket\WsServerInterface;
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Symfony\Component\Routing\Matcher\UrlMatcher;
|
||||
|
||||
|
||||
/**
|
||||
* @covers Ratchet\Http\Router
|
||||
*/
|
||||
class RouterTest extends \PHPUnit_Framework_TestCase {
|
||||
protected $_router;
|
||||
protected $_matcher;
|
||||
protected $_conn;
|
||||
protected $_uri;
|
||||
protected $_req;
|
||||
|
||||
public function setUp() {
|
||||
$this->_conn = $this->getMock('\Ratchet\ConnectionInterface');
|
||||
$this->_uri = $this->getMock('Psr\Http\Message\UriInterface');
|
||||
$this->_req = $this->getMock('\Psr\Http\Message\RequestInterface');
|
||||
$this->_req
|
||||
->expects($this->any())
|
||||
->method('getUri')
|
||||
->will($this->returnValue($this->_uri));
|
||||
$this->_matcher = $this->getMock('Symfony\Component\Routing\Matcher\UrlMatcherInterface');
|
||||
$this->_matcher
|
||||
->expects($this->any())
|
||||
->method('getContext')
|
||||
->will($this->returnValue($this->getMock('Symfony\Component\Routing\RequestContext')));
|
||||
$this->_router = new Router($this->_matcher);
|
||||
|
||||
$this->_uri->expects($this->any())->method('getPath')->will($this->returnValue('ws://doesnt.matter/'));
|
||||
$this->_uri->expects($this->any())->method('withQuery')->with($this->callback(function($val) {
|
||||
$this->setResult($val);
|
||||
|
||||
return true;
|
||||
}))->will($this->returnSelf());
|
||||
$this->_uri->expects($this->any())->method('getQuery')->will($this->returnCallback([$this, 'getResult']));
|
||||
$this->_req->expects($this->any())->method('withUri')->will($this->returnSelf());
|
||||
}
|
||||
|
||||
public function testFourOhFour() {
|
||||
$this->_conn->expects($this->once())->method('close');
|
||||
|
||||
$nope = new ResourceNotFoundException;
|
||||
$this->_matcher->expects($this->any())->method('match')->will($this->throwException($nope));
|
||||
|
||||
$this->_router->onOpen($this->_conn, $this->_req);
|
||||
}
|
||||
|
||||
public function testNullRequest() {
|
||||
$this->setExpectedException('\UnexpectedValueException');
|
||||
$this->_router->onOpen($this->_conn);
|
||||
}
|
||||
|
||||
public function testControllerIsMessageComponentInterface() {
|
||||
$this->setExpectedException('\UnexpectedValueException');
|
||||
$this->_matcher->expects($this->any())->method('match')->will($this->returnValue(array('_controller' => new \StdClass)));
|
||||
$this->_router->onOpen($this->_conn, $this->_req);
|
||||
}
|
||||
|
||||
public function testControllerOnOpen() {
|
||||
$controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
|
||||
$this->_matcher->expects($this->any())->method('match')->will($this->returnValue(array('_controller' => $controller)));
|
||||
$this->_router->onOpen($this->_conn, $this->_req);
|
||||
|
||||
$expectedConn = new \PHPUnit_Framework_Constraint_IsInstanceOf('\Ratchet\ConnectionInterface');
|
||||
$controller->expects($this->once())->method('onOpen')->with($expectedConn, $this->_req);
|
||||
|
||||
$this->_matcher->expects($this->any())->method('match')->will($this->returnValue(array('_controller' => $controller)));
|
||||
$this->_router->onOpen($this->_conn, $this->_req);
|
||||
}
|
||||
|
||||
public function testControllerOnMessageBubbles() {
|
||||
$message = "The greatest trick the Devil ever pulled was convincing the world he didn't exist";
|
||||
$controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
|
||||
$controller->expects($this->once())->method('onMessage')->with($this->_conn, $message);
|
||||
|
||||
$this->_conn->controller = $controller;
|
||||
|
||||
$this->_router->onMessage($this->_conn, $message);
|
||||
}
|
||||
|
||||
public function testControllerOnCloseBubbles() {
|
||||
$controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
|
||||
$controller->expects($this->once())->method('onClose')->with($this->_conn);
|
||||
|
||||
$this->_conn->controller = $controller;
|
||||
|
||||
$this->_router->onClose($this->_conn);
|
||||
}
|
||||
|
||||
public function testControllerOnErrorBubbles() {
|
||||
$e= new \Exception('One cannot be betrayed if one has no exceptions');
|
||||
$controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
|
||||
$controller->expects($this->once())->method('onError')->with($this->_conn, $e);
|
||||
|
||||
$this->_conn->controller = $controller;
|
||||
|
||||
$this->_router->onError($this->_conn, $e);
|
||||
}
|
||||
|
||||
public function testRouterGeneratesRouteParameters() {
|
||||
/** @var $controller WsServerInterface */
|
||||
$controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
|
||||
/** @var $matcher UrlMatcherInterface */
|
||||
$this->_matcher->expects($this->any())->method('match')->will(
|
||||
$this->returnValue(['_controller' => $controller, 'foo' => 'bar', 'baz' => 'qux'])
|
||||
);
|
||||
$conn = $this->getMock('Ratchet\Mock\Connection');
|
||||
|
||||
$router = new Router($this->_matcher);
|
||||
|
||||
$router->onOpen($conn, $this->_req);
|
||||
|
||||
$this->assertEquals('foo=bar&baz=qux', $this->_req->getUri()->getQuery());
|
||||
}
|
||||
|
||||
public function testQueryParams() {
|
||||
$controller = $this->getMockBuilder('\Ratchet\WebSocket\WsServer')->disableOriginalConstructor()->getMock();
|
||||
$this->_matcher->expects($this->any())->method('match')->will(
|
||||
$this->returnValue(['_controller' => $controller, 'foo' => 'bar', 'baz' => 'qux'])
|
||||
);
|
||||
|
||||
$conn = $this->getMock('Ratchet\Mock\Connection');
|
||||
$request = $this->getMock('Psr\Http\Message\RequestInterface');
|
||||
$uri = new \GuzzleHttp\Psr7\Uri('ws://doesnt.matter/endpoint?hello=world&foo=nope');
|
||||
|
||||
$request->expects($this->any())->method('getUri')->will($this->returnCallback(function() use (&$uri) {
|
||||
return $uri;
|
||||
}));
|
||||
$request->expects($this->any())->method('withUri')->with($this->callback(function($url) use (&$uri) {
|
||||
$uri = $url;
|
||||
|
||||
return true;
|
||||
}))->will($this->returnSelf());
|
||||
|
||||
$router = new Router($this->_matcher);
|
||||
$router->onOpen($conn, $request);
|
||||
|
||||
$this->assertEquals('foo=nope&baz=qux&hello=world', $request->getUri()->getQuery());
|
||||
$this->assertEquals('ws', $request->getUri()->getScheme());
|
||||
$this->assertEquals('doesnt.matter', $request->getUri()->getHost());
|
||||
}
|
||||
|
||||
public function testImpatientClientOverflow() {
|
||||
$this->_conn->expects($this->once())->method('close');
|
||||
|
||||
$header = "GET /nope HTTP/1.1
|
||||
Upgrade: websocket
|
||||
Connection: upgrade
|
||||
Host: localhost
|
||||
Origin: http://localhost
|
||||
Sec-WebSocket-Version: 13\r\n\r\n";
|
||||
|
||||
$app = new HttpServer(new Router(new UrlMatcher(new RouteCollection, new RequestContext)));
|
||||
$app->onOpen($this->_conn);
|
||||
$app->onMessage($this->_conn, $header);
|
||||
$app->onMessage($this->_conn, 'Silly body');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
namespace Ratchet\Server;
|
||||
use Ratchet\Server\EchoServer;
|
||||
|
||||
class EchoServerTest extends \PHPUnit_Framework_TestCase {
|
||||
protected $_conn;
|
||||
protected $_comp;
|
||||
|
||||
public function setUp() {
|
||||
$this->_conn = $this->getMock('\Ratchet\ConnectionInterface');
|
||||
$this->_comp = new EchoServer;
|
||||
}
|
||||
|
||||
public function testMessageEchod() {
|
||||
$message = 'Tillsonburg, my back still aches when I hear that word.';
|
||||
$this->_conn->expects($this->once())->method('send')->with($message);
|
||||
$this->_comp->onMessage($this->_conn, $message);
|
||||
}
|
||||
|
||||
public function testErrorClosesConnection() {
|
||||
ob_start();
|
||||
$this->_conn->expects($this->once())->method('close');
|
||||
$this->_comp->onError($this->_conn, new \Exception);
|
||||
ob_end_clean();
|
||||
}
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
namespace Ratchet\Application\Server;
|
||||
use Ratchet\Server\FlashPolicy;
|
||||
|
||||
/**
|
||||
* @covers Ratchet\Server\FlashPolicy
|
||||
*/
|
||||
class FlashPolicyTest extends \PHPUnit_Framework_TestCase {
|
||||
|
||||
protected $_policy;
|
||||
|
||||
public function setUp() {
|
||||
$this->_policy = new FlashPolicy();
|
||||
}
|
||||
|
||||
public function testPolicyRender() {
|
||||
$this->_policy->setSiteControl('all');
|
||||
$this->_policy->addAllowedAccess('example.com', '*');
|
||||
$this->_policy->addAllowedAccess('dev.example.com', '*');
|
||||
|
||||
$this->assertInstanceOf('SimpleXMLElement', $this->_policy->renderPolicy());
|
||||
}
|
||||
|
||||
public function testInvalidPolicyReader() {
|
||||
$this->setExpectedException('UnexpectedValueException');
|
||||
$this->_policy->renderPolicy();
|
||||
}
|
||||
|
||||
public function testInvalidDomainPolicyReader() {
|
||||
$this->setExpectedException('UnexpectedValueException');
|
||||
$this->_policy->setSiteControl('all');
|
||||
$this->_policy->addAllowedAccess('dev.example.*', '*');
|
||||
$this->_policy->renderPolicy();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider siteControl
|
||||
*/
|
||||
public function testSiteControlValidation($accept, $permittedCrossDomainPolicies) {
|
||||
$this->assertEquals($accept, $this->_policy->validateSiteControl($permittedCrossDomainPolicies));
|
||||
}
|
||||
|
||||
public static function siteControl() {
|
||||
return array(
|
||||
array(true, 'all')
|
||||
, array(true, 'none')
|
||||
, array(true, 'master-only')
|
||||
, array(false, 'by-content-type')
|
||||
, array(false, 'by-ftp-filename')
|
||||
, array(false, '')
|
||||
, array(false, 'all ')
|
||||
, array(false, 'asdf')
|
||||
, array(false, '@893830')
|
||||
, array(false, '*')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider URI
|
||||
*/
|
||||
public function testDomainValidation($accept, $domain) {
|
||||
$this->assertEquals($accept, $this->_policy->validateDomain($domain));
|
||||
}
|
||||
|
||||
public static function URI() {
|
||||
return array(
|
||||
array(true, '*')
|
||||
, array(true, 'example.com')
|
||||
, array(true, 'exam-ple.com')
|
||||
, array(true, '*.example.com')
|
||||
, array(true, 'www.example.com')
|
||||
, array(true, 'dev.dev.example.com')
|
||||
, array(true, 'http://example.com')
|
||||
, array(true, 'https://example.com')
|
||||
, array(true, 'http://*.example.com')
|
||||
, array(false, 'exam*ple.com')
|
||||
, array(true, '127.0.255.1')
|
||||
, array(true, 'localhost')
|
||||
, array(false, 'www.example.*')
|
||||
, array(false, 'www.exa*le.com')
|
||||
, array(false, 'www.example.*com')
|
||||
, array(false, '*.example.*')
|
||||
, array(false, 'gasldf*$#a0sdf0a8sdf')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ports
|
||||
*/
|
||||
public function testPortValidation($accept, $ports) {
|
||||
$this->assertEquals($accept, $this->_policy->validatePorts($ports));
|
||||
}
|
||||
|
||||
public static function ports() {
|
||||
return array(
|
||||
array(true, '*')
|
||||
, array(true, '80')
|
||||
, array(true, '80,443')
|
||||
, array(true, '507,516-523')
|
||||
, array(true, '507,516-523,333')
|
||||
, array(true, '507,516-523,507,516-523')
|
||||
, array(false, '516-')
|
||||
, array(true, '516-523,11')
|
||||
, array(false, '516,-523,11')
|
||||
, array(false, 'example')
|
||||
, array(false, 'asdf,123')
|
||||
, array(false, '--')
|
||||
, array(false, ',,,')
|
||||
, array(false, '838*')
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddAllowedAccessOnlyAcceptsValidPorts() {
|
||||
$this->setExpectedException('UnexpectedValueException');
|
||||
|
||||
$this->_policy->addAllowedAccess('*', 'nope');
|
||||
}
|
||||
|
||||
public function testSetSiteControlThrowsException() {
|
||||
$this->setExpectedException('UnexpectedValueException');
|
||||
|
||||
$this->_policy->setSiteControl('nope');
|
||||
}
|
||||
|
||||
public function testErrorClosesConnection() {
|
||||
$conn = $this->getMock('\\Ratchet\\ConnectionInterface');
|
||||
$conn->expects($this->once())->method('close');
|
||||
|
||||
$this->_policy->onError($conn, new \Exception);
|
||||
}
|
||||
|
||||
public function testOnMessageSendsString() {
|
||||
$this->_policy->addAllowedAccess('*', '*');
|
||||
|
||||
$conn = $this->getMock('\\Ratchet\\ConnectionInterface');
|
||||
$conn->expects($this->once())->method('send')->with($this->isType('string'));
|
||||
|
||||
$this->_policy->onMessage($conn, ' ');
|
||||
}
|
||||
|
||||
public function testOnOpenExists() {
|
||||
$this->assertTrue(method_exists($this->_policy, 'onOpen'));
|
||||
$conn = $this->getMock('\Ratchet\ConnectionInterface');
|
||||
$this->_policy->onOpen($conn);
|
||||
}
|
||||
|
||||
public function testOnCloseExists() {
|
||||
$this->assertTrue(method_exists($this->_policy, 'onClose'));
|
||||
$conn = $this->getMock('\Ratchet\ConnectionInterface');
|
||||
$this->_policy->onClose($conn);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace Ratchet\Application\Server;
|
||||
use Ratchet\Server\IoConnection;
|
||||
|
||||
/**
|
||||
* @covers Ratchet\Server\IoConnection
|
||||
*/
|
||||
class IoConnectionTest extends \PHPUnit_Framework_TestCase {
|
||||
protected $sock;
|
||||
protected $conn;
|
||||
|
||||
public function setUp() {
|
||||
$this->sock = $this->getMock('\\React\\Socket\\ConnectionInterface');
|
||||
$this->conn = new IoConnection($this->sock);
|
||||
}
|
||||
|
||||
public function testCloseBubbles() {
|
||||
$this->sock->expects($this->once())->method('end');
|
||||
$this->conn->close();
|
||||
}
|
||||
|
||||
public function testSendBubbles() {
|
||||
$msg = '6 hour rides are productive';
|
||||
|
||||
$this->sock->expects($this->once())->method('write')->with($msg);
|
||||
$this->conn->send($msg);
|
||||
}
|
||||
|
||||
public function testSendReturnsSelf() {
|
||||
$this->assertSame($this->conn, $this->conn->send('fluent interface'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
namespace Ratchet\Server;
|
||||
use Ratchet\Server\IoServer;
|
||||
use React\EventLoop\StreamSelectLoop;
|
||||
use React\EventLoop\LoopInterface;
|
||||
use React\Socket\Server;
|
||||
|
||||
/**
|
||||
* @covers Ratchet\Server\IoServer
|
||||
*/
|
||||
class IoServerTest extends \PHPUnit_Framework_TestCase {
|
||||
protected $server;
|
||||
|
||||
protected $app;
|
||||
|
||||
protected $port;
|
||||
|
||||
protected $reactor;
|
||||
|
||||
protected function tickLoop(LoopInterface $loop) {
|
||||
$loop->futureTick(function () use ($loop) {
|
||||
$loop->stop();
|
||||
});
|
||||
|
||||
$loop->run();
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
$this->app = $this->getMock('\\Ratchet\\MessageComponentInterface');
|
||||
|
||||
$loop = new StreamSelectLoop;
|
||||
$this->reactor = new Server(0, $loop);
|
||||
|
||||
$uri = $this->reactor->getAddress();
|
||||
$this->port = parse_url((strpos($uri, '://') === false ? 'tcp://' : '') . $uri, PHP_URL_PORT);
|
||||
$this->server = new IoServer($this->app, $this->reactor, $loop);
|
||||
}
|
||||
|
||||
public function testOnOpen() {
|
||||
$this->app->expects($this->once())->method('onOpen')->with($this->isInstanceOf('\\Ratchet\\ConnectionInterface'));
|
||||
|
||||
$client = stream_socket_client("tcp://localhost:{$this->port}");
|
||||
|
||||
$this->tickLoop($this->server->loop);
|
||||
|
||||
//$this->assertTrue(is_string($this->app->last['onOpen'][0]->remoteAddress));
|
||||
//$this->assertTrue(is_int($this->app->last['onOpen'][0]->resourceId));
|
||||
}
|
||||
|
||||
public function testOnData() {
|
||||
$msg = 'Hello World!';
|
||||
|
||||
$this->app->expects($this->once())->method('onMessage')->with(
|
||||
$this->isInstanceOf('\\Ratchet\\ConnectionInterface')
|
||||
, $msg
|
||||
);
|
||||
|
||||
$client = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||
socket_set_option($client, SOL_SOCKET, SO_REUSEADDR, 1);
|
||||
socket_set_option($client, SOL_SOCKET, SO_SNDBUF, 4096);
|
||||
socket_set_block($client);
|
||||
socket_connect($client, 'localhost', $this->port);
|
||||
|
||||
$this->tickLoop($this->server->loop);
|
||||
|
||||
socket_write($client, $msg);
|
||||
$this->tickLoop($this->server->loop);
|
||||
|
||||
socket_shutdown($client, 1);
|
||||
socket_shutdown($client, 0);
|
||||
socket_close($client);
|
||||
|
||||
$this->tickLoop($this->server->loop);
|
||||
}
|
||||
|
||||
public function testOnClose() {
|
||||
$this->app->expects($this->once())->method('onClose')->with($this->isInstanceOf('\\Ratchet\\ConnectionInterface'));
|
||||
|
||||
$client = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||
socket_set_option($client, SOL_SOCKET, SO_REUSEADDR, 1);
|
||||
socket_set_option($client, SOL_SOCKET, SO_SNDBUF, 4096);
|
||||
socket_set_block($client);
|
||||
socket_connect($client, 'localhost', $this->port);
|
||||
|
||||
$this->tickLoop($this->server->loop);
|
||||
|
||||
socket_shutdown($client, 1);
|
||||
socket_shutdown($client, 0);
|
||||
socket_close($client);
|
||||
|
||||
$this->tickLoop($this->server->loop);
|
||||
}
|
||||
|
||||
public function testFactory() {
|
||||
$this->assertInstanceOf('\\Ratchet\\Server\\IoServer', IoServer::factory($this->app, 0));
|
||||
}
|
||||
|
||||
public function testNoLoopProvidedError() {
|
||||
$this->setExpectedException('RuntimeException');
|
||||
|
||||
$io = new IoServer($this->app, $this->reactor);
|
||||
$io->run();
|
||||
}
|
||||
|
||||
public function testOnErrorPassesException() {
|
||||
$conn = $this->getMock('\\React\\Socket\\ConnectionInterface');
|
||||
$conn->decor = $this->getMock('\\Ratchet\\ConnectionInterface');
|
||||
$err = new \Exception("Nope");
|
||||
|
||||
$this->app->expects($this->once())->method('onError')->with($conn->decor, $err);
|
||||
|
||||
$this->server->handleError($err, $conn);
|
||||
}
|
||||
|
||||
public function onErrorCalledWhenExceptionThrown() {
|
||||
$this->markTestIncomplete("Need to learn how to throw an exception from a mock");
|
||||
|
||||
$conn = $this->getMock('\\React\\Socket\\ConnectionInterface');
|
||||
$this->server->handleConnect($conn);
|
||||
|
||||
$e = new \Exception;
|
||||
$this->app->expects($this->once())->method('onMessage')->with($this->isInstanceOf('\\Ratchet\\ConnectionInterface'), 'f')->will($e);
|
||||
$this->app->expects($this->once())->method('onError')->with($this->instanceOf('\\Ratchet\\ConnectionInterface', $e));
|
||||
|
||||
$this->server->handleData('f', $conn);
|
||||
}
|
||||
}
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
namespace Ratchet\Server;
|
||||
use Ratchet\Server\IpBlackList;
|
||||
|
||||
/**
|
||||
* @covers Ratchet\Server\IpBlackList
|
||||
*/
|
||||
class IpBlackListTest extends \PHPUnit_Framework_TestCase {
|
||||
protected $blocker;
|
||||
protected $mock;
|
||||
|
||||
public function setUp() {
|
||||
$this->mock = $this->getMock('\\Ratchet\\MessageComponentInterface');
|
||||
$this->blocker = new IpBlackList($this->mock);
|
||||
}
|
||||
|
||||
public function testOnOpen() {
|
||||
$this->mock->expects($this->exactly(3))->method('onOpen');
|
||||
|
||||
$conn1 = $this->newConn();
|
||||
$conn2 = $this->newConn();
|
||||
$conn3 = $this->newConn();
|
||||
|
||||
$this->blocker->onOpen($conn1);
|
||||
$this->blocker->onOpen($conn3);
|
||||
$this->blocker->onOpen($conn2);
|
||||
}
|
||||
|
||||
public function testBlockDoesNotTriggerOnOpen() {
|
||||
$conn = $this->newConn();
|
||||
|
||||
$this->blocker->blockAddress($conn->remoteAddress);
|
||||
|
||||
$this->mock->expects($this->never())->method('onOpen');
|
||||
|
||||
$ret = $this->blocker->onOpen($conn);
|
||||
}
|
||||
|
||||
public function testBlockDoesNotTriggerOnClose() {
|
||||
$conn = $this->newConn();
|
||||
|
||||
$this->blocker->blockAddress($conn->remoteAddress);
|
||||
|
||||
$this->mock->expects($this->never())->method('onClose');
|
||||
|
||||
$ret = $this->blocker->onOpen($conn);
|
||||
}
|
||||
|
||||
public function testOnMessageDecoration() {
|
||||
$conn = $this->newConn();
|
||||
$msg = 'Hello not being blocked';
|
||||
|
||||
$this->mock->expects($this->once())->method('onMessage')->with($conn, $msg);
|
||||
|
||||
$this->blocker->onMessage($conn, $msg);
|
||||
}
|
||||
|
||||
public function testOnCloseDecoration() {
|
||||
$conn = $this->newConn();
|
||||
|
||||
$this->mock->expects($this->once())->method('onClose')->with($conn);
|
||||
|
||||
$this->blocker->onClose($conn);
|
||||
}
|
||||
|
||||
public function testBlockClosesConnection() {
|
||||
$conn = $this->newConn();
|
||||
$this->blocker->blockAddress($conn->remoteAddress);
|
||||
|
||||
$conn->expects($this->once())->method('close');
|
||||
|
||||
$this->blocker->onOpen($conn);
|
||||
}
|
||||
|
||||
public function testAddAndRemoveWithFluentInterfaces() {
|
||||
$blockOne = '127.0.0.1';
|
||||
$blockTwo = '192.168.1.1';
|
||||
$unblock = '75.119.207.140';
|
||||
|
||||
$this->blocker
|
||||
->blockAddress($unblock)
|
||||
->blockAddress($blockOne)
|
||||
->unblockAddress($unblock)
|
||||
->blockAddress($blockTwo)
|
||||
;
|
||||
|
||||
$this->assertEquals(array($blockOne, $blockTwo), $this->blocker->getBlockedAddresses());
|
||||
}
|
||||
|
||||
public function testDecoratorPassesErrors() {
|
||||
$conn = $this->newConn();
|
||||
$e = new \Exception('I threw an error');
|
||||
|
||||
$this->mock->expects($this->once())->method('onError')->with($conn, $e);
|
||||
|
||||
$this->blocker->onError($conn, $e);
|
||||
}
|
||||
|
||||
public function addressProvider() {
|
||||
return array(
|
||||
array('127.0.0.1', '127.0.0.1')
|
||||
, array('localhost', 'localhost')
|
||||
, array('fe80::1%lo0', 'fe80::1%lo0')
|
||||
, array('127.0.0.1', '127.0.0.1:6392')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider addressProvider
|
||||
*/
|
||||
public function testFilterAddress($expected, $input) {
|
||||
$this->assertEquals($expected, $this->blocker->filterAddress($input));
|
||||
}
|
||||
|
||||
public function testUnblockingSilentlyFails() {
|
||||
$this->assertInstanceOf('\\Ratchet\\Server\\IpBlackList', $this->blocker->unblockAddress('localhost'));
|
||||
}
|
||||
|
||||
protected function newConn() {
|
||||
$conn = $this->getMock('\\Ratchet\\ConnectionInterface');
|
||||
$conn->remoteAddress = '127.0.0.1';
|
||||
|
||||
return $conn;
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
namespace Ratchet\Session\Serialize;
|
||||
use Ratchet\Session\Serialize\PhpHandler;
|
||||
|
||||
/**
|
||||
* @covers Ratchet\Session\Serialize\PhpHandler
|
||||
*/
|
||||
class PhpHandlerTest extends \PHPUnit_Framework_TestCase {
|
||||
protected $_handler;
|
||||
|
||||
public function setUp() {
|
||||
$this->_handler = new PhpHandler;
|
||||
}
|
||||
|
||||
public function serializedProvider() {
|
||||
return array(
|
||||
array(
|
||||
'_sf2_attributes|a:2:{s:5:"hello";s:5:"world";s:4:"last";i:1332872102;}_sf2_flashes|a:0:{}'
|
||||
, array(
|
||||
'_sf2_attributes' => array(
|
||||
'hello' => 'world'
|
||||
, 'last' => 1332872102
|
||||
)
|
||||
, '_sf2_flashes' => array()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider serializedProvider
|
||||
*/
|
||||
public function testUnserialize($in, $expected) {
|
||||
$this->assertEquals($expected, $this->_handler->unserialize($in));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider serializedProvider
|
||||
*/
|
||||
public function testSerialize($serialized, $original) {
|
||||
$this->assertEquals($serialized, $this->_handler->serialize($original));
|
||||
}
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
namespace Ratchet\Session;
|
||||
use Ratchet\AbstractMessageComponentTestCase;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
|
||||
|
||||
/**
|
||||
* @covers Ratchet\Session\SessionProvider
|
||||
* @covers Ratchet\Session\Storage\VirtualSessionStorage
|
||||
* @covers Ratchet\Session\Storage\Proxy\VirtualProxy
|
||||
*/
|
||||
class SessionProviderTest extends AbstractMessageComponentTestCase {
|
||||
public function setUp() {
|
||||
return $this->markTestIncomplete('Test needs to be updated for ini_set issue in PHP 7.2');
|
||||
|
||||
if (!class_exists('Symfony\Component\HttpFoundation\Session\Session')) {
|
||||
return $this->markTestSkipped('Dependency of Symfony HttpFoundation failed');
|
||||
}
|
||||
|
||||
parent::setUp();
|
||||
$this->_serv = new SessionProvider($this->_app, new NullSessionHandler);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
ini_set('session.serialize_handler', 'php');
|
||||
}
|
||||
|
||||
public function getConnectionClassString() {
|
||||
return '\Ratchet\ConnectionInterface';
|
||||
}
|
||||
|
||||
public function getDecoratorClassString() {
|
||||
return '\Ratchet\NullComponent';
|
||||
}
|
||||
|
||||
public function getComponentClassString() {
|
||||
return '\Ratchet\Http\HttpServerInterface';
|
||||
}
|
||||
|
||||
public function classCaseProvider() {
|
||||
return array(
|
||||
array('php', 'Php')
|
||||
, array('php_binary', 'PhpBinary')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider classCaseProvider
|
||||
*/
|
||||
public function testToClassCase($in, $out) {
|
||||
$ref = new \ReflectionClass('\\Ratchet\\Session\\SessionProvider');
|
||||
$method = $ref->getMethod('toClassCase');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$component = new SessionProvider($this->getMock($this->getComponentClassString()), $this->getMock('\SessionHandlerInterface'));
|
||||
$this->assertEquals($out, $method->invokeArgs($component, array($in)));
|
||||
}
|
||||
|
||||
/**
|
||||
* I think I have severely butchered this test...it's not so much of a unit test as it is a full-fledged component test
|
||||
*/
|
||||
public function testConnectionValueFromPdo() {
|
||||
if (!extension_loaded('PDO') || !extension_loaded('pdo_sqlite')) {
|
||||
return $this->markTestSkipped('Session test requires PDO and pdo_sqlite');
|
||||
}
|
||||
|
||||
$sessionId = md5('testSession');
|
||||
|
||||
$dbOptions = array(
|
||||
'db_table' => 'sessions'
|
||||
, 'db_id_col' => 'sess_id'
|
||||
, 'db_data_col' => 'sess_data'
|
||||
, 'db_time_col' => 'sess_time'
|
||||
, 'db_lifetime_col' => 'sess_lifetime'
|
||||
);
|
||||
|
||||
$pdo = new \PDO("sqlite::memory:");
|
||||
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
$pdo->exec(vsprintf("CREATE TABLE %s (%s TEXT NOT NULL PRIMARY KEY, %s BLOB NOT NULL, %s INTEGER NOT NULL, %s INTEGER)", $dbOptions));
|
||||
|
||||
$pdoHandler = new PdoSessionHandler($pdo, $dbOptions);
|
||||
$pdoHandler->write($sessionId, '_sf2_attributes|a:2:{s:5:"hello";s:5:"world";s:4:"last";i:1332872102;}_sf2_flashes|a:0:{}');
|
||||
|
||||
$component = new SessionProvider($this->getMock($this->getComponentClassString()), $pdoHandler, array('auto_start' => 1));
|
||||
$connection = $this->getMock('Ratchet\\ConnectionInterface');
|
||||
|
||||
$headers = $this->getMock('Psr\Http\Message\RequestInterface');
|
||||
$headers->expects($this->once())->method('getHeader')->will($this->returnValue([ini_get('session.name') . "={$sessionId};"]));
|
||||
|
||||
$component->onOpen($connection, $headers);
|
||||
|
||||
$this->assertEquals('world', $connection->Session->get('hello'));
|
||||
}
|
||||
|
||||
protected function newConn() {
|
||||
$conn = $this->getMock('Ratchet\ConnectionInterface');
|
||||
|
||||
$headers = $this->getMock('Psr\Http\Message\Request', array('getCookie'), array('POST', '/', array()));
|
||||
$headers->expects($this->once())->method('getCookie', array(ini_get('session.name')))->will($this->returnValue(null));
|
||||
|
||||
return $conn;
|
||||
}
|
||||
|
||||
public function testOnMessageDecorator() {
|
||||
$message = "Database calls are usually blocking :(";
|
||||
$this->_app->expects($this->once())->method('onMessage')->with($this->isExpectedConnection(), $message);
|
||||
$this->_serv->onMessage($this->_conn, $message);
|
||||
}
|
||||
|
||||
public function testRejectInvalidSeralizers() {
|
||||
if (!function_exists('wddx_serialize_value')) {
|
||||
$this->markTestSkipped();
|
||||
}
|
||||
|
||||
ini_set('session.serialize_handler', 'wddx');
|
||||
$this->setExpectedException('\RuntimeException');
|
||||
new SessionProvider($this->getMock($this->getComponentClassString()), $this->getMock('\SessionHandlerInterface'));
|
||||
}
|
||||
|
||||
protected function doOpen($conn) {
|
||||
$request = $this->getMock('Psr\Http\Message\RequestInterface');
|
||||
$request->expects($this->any())->method('getHeader')->will($this->returnValue([]));
|
||||
|
||||
$this->_serv->onOpen($conn, $request);
|
||||
}
|
||||
}
|
||||
Vendored
+53
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
namespace Ratchet\Session\Storage;
|
||||
use Ratchet\Session\Serialize\PhpHandler;
|
||||
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
|
||||
use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
|
||||
|
||||
class VirtualSessionStoragePDOTest extends \PHPUnit_Framework_TestCase {
|
||||
/**
|
||||
* @var VirtualSessionStorage
|
||||
*/
|
||||
protected $_virtualSessionStorage;
|
||||
|
||||
protected $_pathToDB;
|
||||
|
||||
public function setUp() {
|
||||
if (!extension_loaded('PDO') || !extension_loaded('pdo_sqlite')) {
|
||||
return $this->markTestSkipped('Session test requires PDO and pdo_sqlite');
|
||||
}
|
||||
|
||||
$schema = <<<SQL
|
||||
CREATE TABLE `sessions` (
|
||||
`sess_id` VARBINARY(128) NOT NULL PRIMARY KEY,
|
||||
`sess_data` BLOB NOT NULL,
|
||||
`sess_time` INTEGER UNSIGNED NOT NULL,
|
||||
`sess_lifetime` MEDIUMINT NOT NULL
|
||||
);
|
||||
SQL;
|
||||
$this->_pathToDB = tempnam(sys_get_temp_dir(), 'SQ3');;
|
||||
$dsn = 'sqlite:' . $this->_pathToDB;
|
||||
|
||||
$pdo = new \PDO($dsn);
|
||||
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
$pdo->exec($schema);
|
||||
$pdo = null;
|
||||
|
||||
$sessionHandler = new PdoSessionHandler($dsn);
|
||||
$serializer = new PhpHandler();
|
||||
$this->_virtualSessionStorage = new VirtualSessionStorage($sessionHandler, 'foobar', $serializer);
|
||||
$this->_virtualSessionStorage->registerBag(new FlashBag());
|
||||
$this->_virtualSessionStorage->registerBag(new AttributeBag());
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
unlink($this->_pathToDB);
|
||||
}
|
||||
|
||||
public function testStartWithDSN() {
|
||||
$this->_virtualSessionStorage->start();
|
||||
|
||||
$this->assertTrue($this->_virtualSessionStorage->isStarted());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
<?php
|
||||
namespace Ratchet\Wamp;
|
||||
use Ratchet\Mock\Connection;
|
||||
use Ratchet\Mock\WampComponent as TestComponent;
|
||||
|
||||
/**
|
||||
* @covers \Ratchet\Wamp\ServerProtocol
|
||||
* @covers \Ratchet\Wamp\WampServerInterface
|
||||
* @covers \Ratchet\Wamp\WampConnection
|
||||
*/
|
||||
class ServerProtocolTest extends \PHPUnit_Framework_TestCase {
|
||||
protected $_comp;
|
||||
|
||||
protected $_app;
|
||||
|
||||
public function setUp() {
|
||||
$this->_app = new TestComponent;
|
||||
$this->_comp = new ServerProtocol($this->_app);
|
||||
}
|
||||
|
||||
protected function newConn() {
|
||||
return new Connection;
|
||||
}
|
||||
|
||||
public function invalidMessageProvider() {
|
||||
return [
|
||||
[0]
|
||||
, [3]
|
||||
, [4]
|
||||
, [8]
|
||||
, [9]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider invalidMessageProvider
|
||||
*/
|
||||
public function testInvalidMessages($type) {
|
||||
$this->setExpectedException('\Ratchet\Wamp\Exception');
|
||||
|
||||
$conn = $this->newConn();
|
||||
$this->_comp->onOpen($conn);
|
||||
$this->_comp->onMessage($conn, json_encode([$type]));
|
||||
}
|
||||
|
||||
public function testWelcomeMessage() {
|
||||
$conn = $this->newConn();
|
||||
|
||||
$this->_comp->onOpen($conn);
|
||||
|
||||
$message = $conn->last['send'];
|
||||
$json = json_decode($message);
|
||||
|
||||
$this->assertEquals(4, count($json));
|
||||
$this->assertEquals(0, $json[0]);
|
||||
$this->assertTrue(is_string($json[1]));
|
||||
$this->assertEquals(1, $json[2]);
|
||||
}
|
||||
|
||||
public function testSubscribe() {
|
||||
$uri = 'http://example.com';
|
||||
$clientMessage = array(5, $uri);
|
||||
|
||||
$conn = $this->newConn();
|
||||
|
||||
$this->_comp->onOpen($conn);
|
||||
$this->_comp->onMessage($conn, json_encode($clientMessage));
|
||||
|
||||
$this->assertEquals($uri, $this->_app->last['onSubscribe'][1]);
|
||||
}
|
||||
|
||||
public function testUnSubscribe() {
|
||||
$uri = 'http://example.com/endpoint';
|
||||
$clientMessage = array(6, $uri);
|
||||
|
||||
$conn = $this->newConn();
|
||||
|
||||
$this->_comp->onOpen($conn);
|
||||
$this->_comp->onMessage($conn, json_encode($clientMessage));
|
||||
|
||||
$this->assertEquals($uri, $this->_app->last['onUnSubscribe'][1]);
|
||||
}
|
||||
|
||||
public function callProvider() {
|
||||
return [
|
||||
[2, 'a', 'b']
|
||||
, [2, ['a', 'b']]
|
||||
, [1, 'one']
|
||||
, [3, 'one', 'two', 'three']
|
||||
, [3, ['un', 'deux', 'trois']]
|
||||
, [2, 'hi', ['hello', 'world']]
|
||||
, [2, ['hello', 'world'], 'hi']
|
||||
, [2, ['hello' => 'world', 'herp' => 'derp']]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider callProvider
|
||||
*/
|
||||
public function testCall() {
|
||||
$args = func_get_args();
|
||||
$paramNum = array_shift($args);
|
||||
|
||||
$uri = 'http://example.com/endpoint/' . rand(1, 100);
|
||||
$id = uniqid('', false);
|
||||
$clientMessage = array_merge(array(2, $id, $uri), $args);
|
||||
|
||||
$conn = $this->newConn();
|
||||
|
||||
$this->_comp->onOpen($conn);
|
||||
$this->_comp->onMessage($conn, json_encode($clientMessage));
|
||||
|
||||
$this->assertEquals($id, $this->_app->last['onCall'][1]);
|
||||
$this->assertEquals($uri, $this->_app->last['onCall'][2]);
|
||||
|
||||
$this->assertEquals($paramNum, count($this->_app->last['onCall'][3]));
|
||||
}
|
||||
|
||||
public function testPublish() {
|
||||
$conn = $this->newConn();
|
||||
|
||||
$topic = 'pubsubhubbub';
|
||||
$event = 'Here I am, publishing data';
|
||||
|
||||
$clientMessage = array(7, $topic, $event);
|
||||
|
||||
$this->_comp->onOpen($conn);
|
||||
$this->_comp->onMessage($conn, json_encode($clientMessage));
|
||||
|
||||
$this->assertEquals($topic, $this->_app->last['onPublish'][1]);
|
||||
$this->assertEquals($event, $this->_app->last['onPublish'][2]);
|
||||
$this->assertEquals(array(), $this->_app->last['onPublish'][3]);
|
||||
$this->assertEquals(array(), $this->_app->last['onPublish'][4]);
|
||||
}
|
||||
|
||||
public function testPublishAndExcludeMe() {
|
||||
$conn = $this->newConn();
|
||||
|
||||
$this->_comp->onOpen($conn);
|
||||
$this->_comp->onMessage($conn, json_encode(array(7, 'topic', 'event', true)));
|
||||
|
||||
$this->assertEquals($conn->WAMP->sessionId, $this->_app->last['onPublish'][3][0]);
|
||||
}
|
||||
|
||||
public function testPublishAndEligible() {
|
||||
$conn = $this->newConn();
|
||||
|
||||
$buddy = uniqid('', false);
|
||||
$friend = uniqid('', false);
|
||||
|
||||
$this->_comp->onOpen($conn);
|
||||
$this->_comp->onMessage($conn, json_encode(array(7, 'topic', 'event', false, array($buddy, $friend))));
|
||||
|
||||
$this->assertEquals(array(), $this->_app->last['onPublish'][3]);
|
||||
$this->assertEquals(2, count($this->_app->last['onPublish'][4]));
|
||||
}
|
||||
|
||||
public function eventProvider() {
|
||||
return array(
|
||||
array('http://example.com', array('one', 'two'))
|
||||
, array('curie', array(array('hello' => 'world', 'herp' => 'derp')))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider eventProvider
|
||||
*/
|
||||
public function testEvent($topic, $payload) {
|
||||
$conn = new WampConnection($this->newConn());
|
||||
$conn->event($topic, $payload);
|
||||
|
||||
$eventString = $conn->last['send'];
|
||||
|
||||
$this->assertSame(array(8, $topic, $payload), json_decode($eventString, true));
|
||||
}
|
||||
|
||||
public function testOnClosePropagation() {
|
||||
$conn = new Connection;
|
||||
|
||||
$this->_comp->onOpen($conn);
|
||||
$this->_comp->onClose($conn);
|
||||
|
||||
$class = new \ReflectionClass('\\Ratchet\\Wamp\\WampConnection');
|
||||
$method = $class->getMethod('getConnection');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$check = $method->invokeArgs($this->_app->last['onClose'][0], array());
|
||||
|
||||
$this->assertSame($conn, $check);
|
||||
}
|
||||
|
||||
public function testOnErrorPropagation() {
|
||||
$conn = new Connection;
|
||||
|
||||
$e = new \Exception('Nope');
|
||||
|
||||
$this->_comp->onOpen($conn);
|
||||
$this->_comp->onError($conn, $e);
|
||||
|
||||
$class = new \ReflectionClass('\\Ratchet\\Wamp\\WampConnection');
|
||||
$method = $class->getMethod('getConnection');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$check = $method->invokeArgs($this->_app->last['onError'][0], array());
|
||||
|
||||
$this->assertSame($conn, $check);
|
||||
$this->assertSame($e, $this->_app->last['onError'][1]);
|
||||
}
|
||||
|
||||
public function testPrefix() {
|
||||
$conn = new WampConnection($this->newConn());
|
||||
$this->_comp->onOpen($conn);
|
||||
|
||||
$prefix = 'incoming';
|
||||
$fullURI = "http://example.com/$prefix";
|
||||
$method = 'call';
|
||||
|
||||
$this->_comp->onMessage($conn, json_encode(array(1, $prefix, $fullURI)));
|
||||
|
||||
$this->assertEquals($fullURI, $conn->WAMP->prefixes[$prefix]);
|
||||
$this->assertEquals("$fullURI#$method", $conn->getUri("$prefix:$method"));
|
||||
}
|
||||
|
||||
public function testMessageMustBeJson() {
|
||||
$this->setExpectedException('\\Ratchet\\Wamp\\JsonException');
|
||||
|
||||
$conn = new Connection;
|
||||
|
||||
$this->_comp->onOpen($conn);
|
||||
$this->_comp->onMessage($conn, 'Hello World!');
|
||||
}
|
||||
|
||||
public function testGetSubProtocolsReturnsArray() {
|
||||
$this->assertTrue(is_array($this->_comp->getSubProtocols()));
|
||||
}
|
||||
|
||||
public function testGetSubProtocolsGetFromApp() {
|
||||
$this->_app->protocols = array('hello', 'world');
|
||||
|
||||
$this->assertGreaterThanOrEqual(3, count($this->_comp->getSubProtocols()));
|
||||
}
|
||||
|
||||
public function testWampOnMessageApp() {
|
||||
$app = $this->getMock('\\Ratchet\\Wamp\\WampServerInterface');
|
||||
$wamp = new ServerProtocol($app);
|
||||
|
||||
$this->assertContains('wamp', $wamp->getSubProtocols());
|
||||
}
|
||||
|
||||
public function badFormatProvider() {
|
||||
return array(
|
||||
array(json_encode(true))
|
||||
, array('{"valid":"json", "invalid": "message"}')
|
||||
, array('{"0": "fail", "hello": "world"}')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider badFormatProvider
|
||||
*/
|
||||
public function testValidJsonButInvalidProtocol($message) {
|
||||
$this->setExpectedException('\Ratchet\Wamp\Exception');
|
||||
|
||||
$conn = $this->newConn();
|
||||
$this->_comp->onOpen($conn);
|
||||
$this->_comp->onMessage($conn, $message);
|
||||
}
|
||||
|
||||
public function testBadClientInputFromNonStringTopic() {
|
||||
$this->setExpectedException('\Ratchet\Wamp\Exception');
|
||||
|
||||
$conn = new WampConnection($this->newConn());
|
||||
$this->_comp->onOpen($conn);
|
||||
|
||||
$this->_comp->onMessage($conn, json_encode([5, ['hells', 'nope']]));
|
||||
}
|
||||
|
||||
public function testBadPrefixWithNonStringTopic() {
|
||||
$this->setExpectedException('\Ratchet\Wamp\Exception');
|
||||
|
||||
$conn = new WampConnection($this->newConn());
|
||||
$this->_comp->onOpen($conn);
|
||||
|
||||
$this->_comp->onMessage($conn, json_encode([1, ['hells', 'nope'], ['bad', 'input']]));
|
||||
}
|
||||
|
||||
public function testBadPublishWithNonStringTopic() {
|
||||
$this->setExpectedException('\Ratchet\Wamp\Exception');
|
||||
|
||||
$conn = new WampConnection($this->newConn());
|
||||
$this->_comp->onOpen($conn);
|
||||
|
||||
$this->_comp->onMessage($conn, json_encode([7, ['bad', 'input'], 'Hider']));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
namespace Ratchet\Wamp;
|
||||
|
||||
/**
|
||||
* @covers Ratchet\Wamp\TopicManager
|
||||
*/
|
||||
class TopicManagerTest extends \PHPUnit_Framework_TestCase {
|
||||
private $mock;
|
||||
|
||||
/**
|
||||
* @var \Ratchet\Wamp\TopicManager
|
||||
*/
|
||||
private $mngr;
|
||||
|
||||
/**
|
||||
* @var \Ratchet\ConnectionInterface
|
||||
*/
|
||||
private $conn;
|
||||
|
||||
public function setUp() {
|
||||
$this->conn = $this->getMock('\Ratchet\ConnectionInterface');
|
||||
$this->mock = $this->getMock('\Ratchet\Wamp\WampServerInterface');
|
||||
$this->mngr = new TopicManager($this->mock);
|
||||
|
||||
$this->conn->WAMP = new \StdClass;
|
||||
$this->mngr->onOpen($this->conn);
|
||||
}
|
||||
|
||||
public function testGetTopicReturnsTopicObject() {
|
||||
$class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
|
||||
$method = $class->getMethod('getTopic');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$topic = $method->invokeArgs($this->mngr, array('The Topic'));
|
||||
|
||||
$this->assertInstanceOf('Ratchet\Wamp\Topic', $topic);
|
||||
}
|
||||
|
||||
public function testGetTopicCreatesTopicWithSameName() {
|
||||
$name = 'The Topic';
|
||||
|
||||
$class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
|
||||
$method = $class->getMethod('getTopic');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$topic = $method->invokeArgs($this->mngr, array($name));
|
||||
|
||||
$this->assertEquals($name, $topic->getId());
|
||||
}
|
||||
|
||||
public function testGetTopicReturnsSameObject() {
|
||||
$class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
|
||||
$method = $class->getMethod('getTopic');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$topic = $method->invokeArgs($this->mngr, array('No copy'));
|
||||
$again = $method->invokeArgs($this->mngr, array('No copy'));
|
||||
|
||||
$this->assertSame($topic, $again);
|
||||
}
|
||||
|
||||
public function testOnOpen() {
|
||||
$this->mock->expects($this->once())->method('onOpen');
|
||||
$this->mngr->onOpen($this->conn);
|
||||
}
|
||||
|
||||
public function testOnCall() {
|
||||
$id = uniqid();
|
||||
|
||||
$this->mock->expects($this->once())->method('onCall')->with(
|
||||
$this->conn
|
||||
, $id
|
||||
, $this->isInstanceOf('Ratchet\Wamp\Topic')
|
||||
, array()
|
||||
);
|
||||
|
||||
$this->mngr->onCall($this->conn, $id, 'new topic', array());
|
||||
}
|
||||
|
||||
public function testOnSubscribeCreatesTopicObject() {
|
||||
$this->mock->expects($this->once())->method('onSubscribe')->with(
|
||||
$this->conn, $this->isInstanceOf('Ratchet\Wamp\Topic')
|
||||
);
|
||||
|
||||
$this->mngr->onSubscribe($this->conn, 'new topic');
|
||||
}
|
||||
|
||||
public function testTopicIsInConnectionOnSubscribe() {
|
||||
$name = 'New Topic';
|
||||
|
||||
$class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
|
||||
$method = $class->getMethod('getTopic');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$topic = $method->invokeArgs($this->mngr, array($name));
|
||||
|
||||
$this->mngr->onSubscribe($this->conn, $name);
|
||||
|
||||
$this->assertTrue($this->conn->WAMP->subscriptions->contains($topic));
|
||||
}
|
||||
|
||||
public function testDoubleSubscriptionFiresOnce() {
|
||||
$this->mock->expects($this->exactly(1))->method('onSubscribe');
|
||||
|
||||
$this->mngr->onSubscribe($this->conn, 'same topic');
|
||||
$this->mngr->onSubscribe($this->conn, 'same topic');
|
||||
}
|
||||
|
||||
public function testUnsubscribeEvent() {
|
||||
$name = 'in and out';
|
||||
$this->mock->expects($this->once())->method('onUnsubscribe')->with(
|
||||
$this->conn, $this->isInstanceOf('Ratchet\Wamp\Topic')
|
||||
);
|
||||
|
||||
$this->mngr->onSubscribe($this->conn, $name);
|
||||
$this->mngr->onUnsubscribe($this->conn, $name);
|
||||
}
|
||||
|
||||
public function testUnsubscribeFiresOnce() {
|
||||
$name = 'getting sleepy';
|
||||
$this->mock->expects($this->exactly(1))->method('onUnsubscribe');
|
||||
|
||||
$this->mngr->onSubscribe($this->conn, $name);
|
||||
$this->mngr->onUnsubscribe($this->conn, $name);
|
||||
$this->mngr->onUnsubscribe($this->conn, $name);
|
||||
}
|
||||
|
||||
public function testUnsubscribeRemovesTopicFromConnection() {
|
||||
$name = 'Bye Bye Topic';
|
||||
|
||||
$class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
|
||||
$method = $class->getMethod('getTopic');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$topic = $method->invokeArgs($this->mngr, array($name));
|
||||
|
||||
$this->mngr->onSubscribe($this->conn, $name);
|
||||
$this->mngr->onUnsubscribe($this->conn, $name);
|
||||
|
||||
$this->assertFalse($this->conn->WAMP->subscriptions->contains($topic));
|
||||
}
|
||||
|
||||
public function testOnPublishBubbles() {
|
||||
$msg = 'Cover all the code!';
|
||||
|
||||
$this->mock->expects($this->once())->method('onPublish')->with(
|
||||
$this->conn
|
||||
, $this->isInstanceOf('Ratchet\Wamp\Topic')
|
||||
, $msg
|
||||
, $this->isType('array')
|
||||
, $this->isType('array')
|
||||
);
|
||||
|
||||
$this->mngr->onPublish($this->conn, 'topic coverage', $msg, array(), array());
|
||||
}
|
||||
|
||||
public function testOnCloseBubbles() {
|
||||
$this->mock->expects($this->once())->method('onClose')->with($this->conn);
|
||||
$this->mngr->onClose($this->conn);
|
||||
}
|
||||
|
||||
protected function topicProvider($name) {
|
||||
$class = new \ReflectionClass('Ratchet\Wamp\TopicManager');
|
||||
$method = $class->getMethod('getTopic');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$attribute = $class->getProperty('topicLookup');
|
||||
$attribute->setAccessible(true);
|
||||
|
||||
$topic = $method->invokeArgs($this->mngr, array($name));
|
||||
|
||||
return array($topic, $attribute);
|
||||
}
|
||||
|
||||
public function testConnIsRemovedFromTopicOnClose() {
|
||||
$name = 'State Testing';
|
||||
list($topic, $attribute) = $this->topicProvider($name);
|
||||
|
||||
$this->assertCount(1, $attribute->getValue($this->mngr));
|
||||
|
||||
$this->mngr->onSubscribe($this->conn, $name);
|
||||
$this->mngr->onClose($this->conn);
|
||||
|
||||
$this->assertFalse($topic->has($this->conn));
|
||||
}
|
||||
|
||||
public static function topicConnExpectationProvider() {
|
||||
return [
|
||||
[ 'onClose', 0]
|
||||
, ['onUnsubscribe', 0]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider topicConnExpectationProvider
|
||||
*/
|
||||
public function testTopicRetentionFromLeavingConnections($methodCall, $expectation) {
|
||||
$topicName = 'checkTopic';
|
||||
list($topic, $attribute) = $this->topicProvider($topicName);
|
||||
|
||||
$this->mngr->onSubscribe($this->conn, $topicName);
|
||||
call_user_func_array(array($this->mngr, $methodCall), array($this->conn, $topicName));
|
||||
|
||||
$this->assertCount($expectation, $attribute->getValue($this->mngr));
|
||||
}
|
||||
|
||||
public function testOnErrorBubbles() {
|
||||
$e = new \Exception('All work and no play makes Chris a dull boy');
|
||||
$this->mock->expects($this->once())->method('onError')->with($this->conn, $e);
|
||||
|
||||
$this->mngr->onError($this->conn, $e);
|
||||
}
|
||||
|
||||
public function testGetSubProtocolsReturnsArray() {
|
||||
$this->assertInternalType('array', $this->mngr->getSubProtocols());
|
||||
}
|
||||
|
||||
public function testGetSubProtocolsBubbles() {
|
||||
$subs = array('hello', 'world');
|
||||
$app = $this->getMock('Ratchet\Wamp\Stub\WsWampServerInterface');
|
||||
$app->expects($this->once())->method('getSubProtocols')->will($this->returnValue($subs));
|
||||
$mngr = new TopicManager($app);
|
||||
|
||||
$this->assertEquals($subs, $mngr->getSubProtocols());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
namespace Ratchet\Wamp;
|
||||
|
||||
/**
|
||||
* @covers Ratchet\Wamp\Topic
|
||||
*/
|
||||
class TopicTest extends \PHPUnit_Framework_TestCase {
|
||||
public function testGetId() {
|
||||
$id = uniqid();
|
||||
$topic = new Topic($id);
|
||||
|
||||
$this->assertEquals($id, $topic->getId());
|
||||
}
|
||||
|
||||
public function testAddAndCount() {
|
||||
$topic = new Topic('merp');
|
||||
|
||||
$topic->add($this->newConn());
|
||||
$topic->add($this->newConn());
|
||||
$topic->add($this->newConn());
|
||||
|
||||
$this->assertEquals(3, count($topic));
|
||||
}
|
||||
|
||||
public function testRemove() {
|
||||
$topic = new Topic('boop');
|
||||
$tracked = $this->newConn();
|
||||
|
||||
$topic->add($this->newConn());
|
||||
$topic->add($tracked);
|
||||
$topic->add($this->newConn());
|
||||
|
||||
$topic->remove($tracked);
|
||||
|
||||
$this->assertEquals(2, count($topic));
|
||||
}
|
||||
|
||||
public function testBroadcast() {
|
||||
$msg = 'Hello World!';
|
||||
$name = 'Batman';
|
||||
$protocol = json_encode(array(8, $name, $msg));
|
||||
|
||||
$first = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
|
||||
$second = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
|
||||
|
||||
$first->expects($this->once())
|
||||
->method('send')
|
||||
->with($this->equalTo($protocol));
|
||||
|
||||
$second->expects($this->once())
|
||||
->method('send')
|
||||
->with($this->equalTo($protocol));
|
||||
|
||||
$topic = new Topic($name);
|
||||
$topic->add($first);
|
||||
$topic->add($second);
|
||||
|
||||
$topic->broadcast($msg);
|
||||
}
|
||||
|
||||
public function testBroadcastWithExclude() {
|
||||
$msg = 'Hello odd numbers';
|
||||
$name = 'Excluding';
|
||||
$protocol = json_encode(array(8, $name, $msg));
|
||||
|
||||
$first = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
|
||||
$second = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
|
||||
$third = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
|
||||
|
||||
$first->expects($this->once())
|
||||
->method('send')
|
||||
->with($this->equalTo($protocol));
|
||||
|
||||
$second->expects($this->never())->method('send');
|
||||
|
||||
$third->expects($this->once())
|
||||
->method('send')
|
||||
->with($this->equalTo($protocol));
|
||||
|
||||
$topic = new Topic($name);
|
||||
$topic->add($first);
|
||||
$topic->add($second);
|
||||
$topic->add($third);
|
||||
|
||||
$topic->broadcast($msg, array($second->WAMP->sessionId));
|
||||
}
|
||||
|
||||
public function testBroadcastWithEligible() {
|
||||
$msg = 'Hello white list';
|
||||
$name = 'Eligible';
|
||||
$protocol = json_encode(array(8, $name, $msg));
|
||||
|
||||
$first = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
|
||||
$second = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
|
||||
$third = $this->getMock('Ratchet\\Wamp\\WampConnection', array('send'), array($this->getMock('\\Ratchet\\ConnectionInterface')));
|
||||
|
||||
$first->expects($this->once())
|
||||
->method('send')
|
||||
->with($this->equalTo($protocol));
|
||||
|
||||
$second->expects($this->never())->method('send');
|
||||
|
||||
$third->expects($this->once())
|
||||
->method('send')
|
||||
->with($this->equalTo($protocol));
|
||||
|
||||
$topic = new Topic($name);
|
||||
$topic->add($first);
|
||||
$topic->add($second);
|
||||
$topic->add($third);
|
||||
|
||||
$topic->broadcast($msg, array(), array($first->WAMP->sessionId, $third->WAMP->sessionId));
|
||||
}
|
||||
|
||||
public function testIterator() {
|
||||
$first = $this->newConn();
|
||||
$second = $this->newConn();
|
||||
$third = $this->newConn();
|
||||
|
||||
$topic = new Topic('Joker');
|
||||
$topic->add($first)->add($second)->add($third);
|
||||
|
||||
$check = array($first, $second, $third);
|
||||
|
||||
foreach ($topic as $mock) {
|
||||
$this->assertNotSame(false, array_search($mock, $check));
|
||||
}
|
||||
}
|
||||
|
||||
public function testToString() {
|
||||
$name = 'Bane';
|
||||
$topic = new Topic($name);
|
||||
|
||||
$this->assertEquals($name, (string)$topic);
|
||||
}
|
||||
|
||||
public function testDoesHave() {
|
||||
$conn = $this->newConn();
|
||||
$topic = new Topic('Two Face');
|
||||
$topic->add($conn);
|
||||
|
||||
$this->assertTrue($topic->has($conn));
|
||||
}
|
||||
|
||||
public function testDoesNotHave() {
|
||||
$conn = $this->newConn();
|
||||
$topic = new Topic('Alfred');
|
||||
|
||||
$this->assertFalse($topic->has($conn));
|
||||
}
|
||||
|
||||
public function testDoesNotHaveAfterRemove() {
|
||||
$conn = $this->newConn();
|
||||
$topic = new Topic('Ras');
|
||||
|
||||
$topic->add($conn)->remove($conn);
|
||||
|
||||
$this->assertFalse($topic->has($conn));
|
||||
}
|
||||
|
||||
protected function newConn() {
|
||||
return new WampConnection($this->getMock('\\Ratchet\\ConnectionInterface'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
namespace Ratchet\Wamp;
|
||||
|
||||
/**
|
||||
* @covers Ratchet\Wamp\WampConnection
|
||||
*/
|
||||
class WampConnectionTest extends \PHPUnit_Framework_TestCase {
|
||||
protected $conn;
|
||||
protected $mock;
|
||||
|
||||
public function setUp() {
|
||||
$this->mock = $this->getMock('\\Ratchet\\ConnectionInterface');
|
||||
$this->conn = new WampConnection($this->mock);
|
||||
}
|
||||
|
||||
public function testCallResult() {
|
||||
$callId = uniqid();
|
||||
$data = array('hello' => 'world', 'herp' => 'derp');
|
||||
|
||||
$this->mock->expects($this->once())->method('send')->with(json_encode(array(3, $callId, $data)));
|
||||
|
||||
$this->conn->callResult($callId, $data);
|
||||
}
|
||||
|
||||
public function testCallError() {
|
||||
$callId = uniqid();
|
||||
$uri = 'http://example.com/end/point';
|
||||
|
||||
$this->mock->expects($this->once())->method('send')->with(json_encode(array(4, $callId, $uri, '')));
|
||||
|
||||
$this->conn->callError($callId, $uri);
|
||||
}
|
||||
|
||||
public function testCallErrorWithTopic() {
|
||||
$callId = uniqid();
|
||||
$uri = 'http://example.com/end/point';
|
||||
|
||||
$this->mock->expects($this->once())->method('send')->with(json_encode(array(4, $callId, $uri, '')));
|
||||
|
||||
$this->conn->callError($callId, new Topic($uri));
|
||||
}
|
||||
|
||||
public function testDetailedCallError() {
|
||||
$callId = uniqid();
|
||||
$uri = 'http://example.com/end/point';
|
||||
$desc = 'beep boop beep';
|
||||
$detail = 'Error: Too much awesome';
|
||||
|
||||
$this->mock->expects($this->once())->method('send')->with(json_encode(array(4, $callId, $uri, $desc, $detail)));
|
||||
|
||||
$this->conn->callError($callId, $uri, $desc, $detail);
|
||||
}
|
||||
|
||||
public function testPrefix() {
|
||||
$shortOut = 'outgoing';
|
||||
$longOut = 'http://example.com/outgoing';
|
||||
|
||||
$this->mock->expects($this->once())->method('send')->with(json_encode(array(1, $shortOut, $longOut)));
|
||||
|
||||
$this->conn->prefix($shortOut, $longOut);
|
||||
}
|
||||
|
||||
public function testGetUriWhenNoCurieGiven() {
|
||||
$uri = 'http://example.com/noshort';
|
||||
|
||||
$this->assertEquals($uri, $this->conn->getUri($uri));
|
||||
}
|
||||
|
||||
public function testClose() {
|
||||
$mock = $this->getMock('\\Ratchet\\ConnectionInterface');
|
||||
$conn = new WampConnection($mock);
|
||||
|
||||
$mock->expects($this->once())->method('close');
|
||||
|
||||
$conn->close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
namespace Ratchet\Wamp;
|
||||
use Ratchet\AbstractMessageComponentTestCase;
|
||||
|
||||
/**
|
||||
* @covers Ratchet\Wamp\WampServer
|
||||
*/
|
||||
class WampServerTest extends AbstractMessageComponentTestCase {
|
||||
public function getConnectionClassString() {
|
||||
return '\Ratchet\Wamp\WampConnection';
|
||||
}
|
||||
|
||||
public function getDecoratorClassString() {
|
||||
return 'Ratchet\Wamp\WampServer';
|
||||
}
|
||||
|
||||
public function getComponentClassString() {
|
||||
return '\Ratchet\Wamp\WampServerInterface';
|
||||
}
|
||||
|
||||
public function testOnMessageToEvent() {
|
||||
$published = 'Client published this message';
|
||||
|
||||
$this->_app->expects($this->once())->method('onPublish')->with(
|
||||
$this->isExpectedConnection()
|
||||
, new \PHPUnit_Framework_Constraint_IsInstanceOf('\Ratchet\Wamp\Topic')
|
||||
, $published
|
||||
, array()
|
||||
, array()
|
||||
);
|
||||
|
||||
$this->_serv->onMessage($this->_conn, json_encode(array(7, 'topic', $published)));
|
||||
}
|
||||
|
||||
public function testGetSubProtocols() {
|
||||
// todo: could expand on this
|
||||
$this->assertInternalType('array', $this->_serv->getSubProtocols());
|
||||
}
|
||||
|
||||
public function testConnectionClosesOnInvalidJson() {
|
||||
$this->_conn->expects($this->once())->method('close');
|
||||
$this->_serv->onMessage($this->_conn, 'invalid json');
|
||||
}
|
||||
|
||||
public function testConnectionClosesOnProtocolError() {
|
||||
$this->_conn->expects($this->once())->method('close');
|
||||
$this->_serv->onMessage($this->_conn, json_encode(array('valid' => 'json', 'invalid' => 'protocol')));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user