Skip to content

Commit

Permalink
save
Browse files Browse the repository at this point in the history
  • Loading branch information
chaz6chez committed Jul 4, 2024
1 parent 1eaabb7 commit d9d5214
Show file tree
Hide file tree
Showing 7 changed files with 349 additions and 62 deletions.
12 changes: 7 additions & 5 deletions src/ApiRoute.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,21 @@ class ApiRoute implements Bootstrap
protected static array $_middlewares = [];

/** @inheritDoc */
public static function start($worker): void
public static function start($worker, $configPath = null): void
{
ApiRoute::initCollector();
ApiRoute::initRoutes();
ApiRoute::initRoutes($configPath);
ApiRoute::initDispatcher();
}

/**
* @param null $configPath
* @return void
*/
public static function initRoutes(): void
public static function initRoutes($configPath = null): void
{
if (is_file($file = config_path() . '/plugin/workbunny/webman-push-server/route.php')) {
if (is_file($file = ($configPath ?: config_path()) . '/plugin/workbunny/webman-push-server/route.php')) {

require_once $file;
}
}
Expand Down Expand Up @@ -132,7 +134,7 @@ public static function getCollector(): ?RouteCollector
*/
public static function initDispatcher(): void
{
if(!self::$_dispatcher){
if (!self::$_dispatcher) {
self::$_dispatcher = new Dispatcher\GroupCountBased(self::getCollector()->getData());
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/config/plugin/workbunny/webman-push-server/route.php
Original file line number Diff line number Diff line change
Expand Up @@ -292,10 +292,10 @@
if (!($appKey = $request->get('auth_key'))) {
return response(400,['error' => 'Required auth_key']);
}
if ($appVerifyCallback = ApiServer::getConfig('app_verify')) {
if ($appVerifyCallback = ApiServer::getConfig('app_verify', getBase: true)) {
if (
!$app = call_user_func($appVerifyCallback, $appKey) or
($app['app_id'] !== $appId)
($app['app_id'] !== intval($appId))
) {
return response(401,['error' => 'Invalid auth_key']);
}
Expand Down
134 changes: 134 additions & 0 deletions tests/ApiServerBaseTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<?php
/**
* This file is part of workbunny.
*
* Redistributions of files must retain the above copyright notice.
*
* @author chaz6chez<[email protected]>
* @copyright chaz6chez<[email protected]>
* @link https://github.com/workbunny/webman-push-server
* @license https://github.com/workbunny/webman-push-server/blob/main/LICENSE
*/
declare(strict_types=1);

namespace Tests;

use Tests\MockClass\MockTcpConnection;
use Webman\Http\Request;
use Webman\Http\Response;
use Workbunny\WebmanPushServer\ApiRoute;

/**
* @runTestsInSeparateProcesses
*/
class ApiServerBaseTest extends BaseTestCase
{


public function testApiServerOnMessageSuccessful()
{
$mockConnection = new MockTcpConnection();
$request = new Request("GET /index HTTP/1.1\r\nConnection: keep-alive\r\n");
// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, $request);

$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('Hello Workbunny!', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(200, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));
}


public function testApiServerOnMessageWithNormalStringData()
{
$mockConnection = new MockTcpConnection();

// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, '');

$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('Bad Request.', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(400, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));

$mockConnection = new MockTcpConnection();

// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, 'test');

$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('Bad Request.', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(400, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));
}


public function testApiServerOnMessageWithBoolData()
{
$mockConnection = new MockTcpConnection();

// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, true);

$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('Bad Request.', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(400, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));

$mockConnection = new MockTcpConnection();

// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, false);

$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('Bad Request.', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(400, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));
}


public function testApiServerOnMessageWithNumberData()
{
$mockConnection = new MockTcpConnection();

// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, 1.1);

$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('Bad Request.', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(400, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));

// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, 1);

$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('Bad Request.', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(400, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));
}


public function testApiServerOnMessageWithArrayData()
{
$mockConnection = new MockTcpConnection();

// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, []);

$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('Bad Request.', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(400, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));

// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, [
'test'
]);

$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('Bad Request.', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(400, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));
}
}
177 changes: 177 additions & 0 deletions tests/ApiServerRouteTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
<?php
/**
* This file is part of workbunny.
*
* Redistributions of files must retain the above copyright notice.
*
* @author chaz6chez<[email protected]>
* @copyright chaz6chez<[email protected]>
* @link https://github.com/workbunny/webman-push-server
* @license https://github.com/workbunny/webman-push-server/blob/main/LICENSE
*/
declare(strict_types=1);

namespace Tests;

use Tests\MockClass\MockTcpConnection;
use Webman\Http\Request;
use Webman\Http\Response;
use Workbunny\WebmanPushServer\ApiClient;

/**
* @runTestsInSeparateProcesses
*/
class ApiServerRouteTest extends BaseTestCase
{

public function testApiServerRouteChannels(){
// required auth_key
$mockConnection = new MockTcpConnection();
$request = new Request("GET /apps/1/channels HTTP/1.1\r\nConnection: keep-alive\r\n");
// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, $request);
$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('{"error":"Required auth_key"}', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(400, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));

// invalid auth_key
$mockConnection = new MockTcpConnection();
$request = new Request("GET /apps/1/channels?auth_key=test HTTP/1.1\r\nConnection: keep-alive\r\n");
// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, $request);
$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('{"error":"Invalid auth_key"}', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(401, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));

// invalid auth_key
$mockConnection = new MockTcpConnection();
$request = new Request("GET /apps/1/channels?auth_key=workbunny&auth_signature=abc HTTP/1.1\r\nConnection: keep-alive\r\n");
// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, $request);
$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('{"error":"Invalid signature"}', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(401, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));

// successful
$mockConnection = new MockTcpConnection();
$signature = ApiClient::routeAuth('workbunny', 'U2FsdGVkX1+vlfFH8Q9XdZ9t9h2bABGYAZltEYAX6UM=', 'GET', '/apps/1/channels', [
'auth_key' => 'workbunny'
]);
$request = new Request("GET /apps/1/channels?auth_key=workbunny&auth_signature=$signature HTTP/1.1\r\nConnection: keep-alive\r\n");
// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, $request);
$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertTrue(isset(json_decode($mockConnection->getSendBuffer()->rawBody(),true)['channels']));
$this->assertEquals(200, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));
}


public function testApiServerRouteChannel(){
$mockConnection = new MockTcpConnection();
$signature = ApiClient::routeAuth('workbunny', 'U2FsdGVkX1+vlfFH8Q9XdZ9t9h2bABGYAZltEYAX6UM=', 'GET', '/apps/1/channels/private-test', [
'auth_key' => 'workbunny'
]);
$request = new Request("GET /apps/1/channels/private-test?auth_key=workbunny&auth_signature=$signature HTTP/1.1\r\nConnection: keep-alive\r\n");
// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, $request);
$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('{"occupied":true,"type":false}', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(200, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));

$mockConnection = new MockTcpConnection();
$signature = ApiClient::routeAuth('workbunny', 'U2FsdGVkX1+vlfFH8Q9XdZ9t9h2bABGYAZltEYAX6UM=', 'GET', '/apps/1/channels/private-test', [
'auth_key' => 'workbunny',
'info' => 'subscription_count'
]);
$request = new Request("GET /apps/1/channels/private-test?auth_key=workbunny&auth_signature=$signature&info=subscription_count HTTP/1.1\r\nConnection: keep-alive\r\n");
// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, $request);
$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('{"occupied":true,"type":false,"subscription_count":false}', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(200, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));

$mockConnection = new MockTcpConnection();
$signature = ApiClient::routeAuth('workbunny', 'U2FsdGVkX1+vlfFH8Q9XdZ9t9h2bABGYAZltEYAX6UM=', 'GET', '/apps/1/channels/private-test', [
'auth_key' => 'workbunny',
'info' => 'subscription_count,user_count'
]);
$request = new Request("GET /apps/1/channels/private-test?auth_key=workbunny&auth_signature=$signature&info=subscription_count,user_count HTTP/1.1\r\nConnection: keep-alive\r\n");
// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, $request);
$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('{"occupied":true,"type":false,"subscription_count":false,"user_count":false}', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(200, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));
}

public function testApiServerRouteEvents(){
$mockConnection = new MockTcpConnection();
$signature = ApiClient::routeAuth('workbunny', 'U2FsdGVkX1+vlfFH8Q9XdZ9t9h2bABGYAZltEYAX6UM=', 'POST', '/apps/1/events', [
'auth_key' => 'workbunny'
]);
$request = new Request("POST /apps/1/events?auth_key=workbunny&auth_signature=$signature HTTP/1.1\r\nConnection: keep-alive\r\n");

// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, $request);

$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('{"error":"Required name"}', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(400, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));
}

public function testApiServerRouteBatchEvents(){

$mockConnection = new MockTcpConnection();
$signature = ApiClient::routeAuth('workbunny', 'U2FsdGVkX1+vlfFH8Q9XdZ9t9h2bABGYAZltEYAX6UM=', 'POST', '/apps/1/batch_events', [
'auth_key' => 'workbunny'
]);
$request = new Request("POST /apps/1/batch_events?auth_key=workbunny&auth_signature=$signature HTTP/1.1\r\nConnection: keep-alive\r\n");

// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, $request);

$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('{"error":"Required batch"}', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(400, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));
}

public function testApiServerRouteUsers(){

$mockConnection = new MockTcpConnection();
$signature = ApiClient::routeAuth('workbunny', 'U2FsdGVkX1+vlfFH8Q9XdZ9t9h2bABGYAZltEYAX6UM=', 'GET', '/apps/1/channels/private-test/users', [
'auth_key' => 'workbunny'
]);
$request = new Request("GET /apps/1/channels/private-test/users?auth_key=workbunny&auth_signature=$signature HTTP/1.1\r\nConnection: keep-alive\r\n");
// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, $request);
$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('{"error":"Not Found [private-test]"}', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(404, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));
}

public function testApiServerRouteTerminateConnections(){

$mockConnection = new MockTcpConnection();
$signature = ApiClient::routeAuth('workbunny', 'U2FsdGVkX1+vlfFH8Q9XdZ9t9h2bABGYAZltEYAX6UM=', 'POST', '/apps/1/users/abc/terminate_connections', [
'auth_key' => 'workbunny'
]);
$request = new Request("POST /apps/1/users/abc/terminate_connections?auth_key=workbunny&auth_signature=$signature HTTP/1.1\r\nConnection: keep-alive\r\n");

// 手动触发 onMessage 回调
$this->getApiServer()->onMessage($mockConnection, $request);

$this->assertTrue($mockConnection->getSendBuffer() instanceof Response);
$this->assertEquals('{}', $mockConnection->getSendBuffer()->rawBody());
$this->assertEquals(200, $mockConnection->getSendBuffer()->getStatusCode());
$this->assertEquals('application/json', $mockConnection->getSendBuffer()->getHeader('Content-Type'));
}
}
16 changes: 8 additions & 8 deletions tests/BaseTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,24 +57,24 @@ public function getApiServer(): ?ApiServer
/** @inheritDoc */
protected function setUp(): void
{
parent::setUp();
// 引入框架文件
// 模拟webman-framework加载框架
require_once __DIR__ . '/../vendor/workerman/webman-framework/src/support/helpers.php';
// 加载配置
// 模拟webman-framework加载配置
Config::load($configPath = __DIR__ . '/../src/config', ['route']);
// 加载bootsrap
// 模拟webman-framework加载bootsrap
foreach (\config('plugin.workbunny.webman-push-server.bootstrap') as $bootstrap) {
if (
class_exists($bootstrap, false) and
class_exists($bootstrap) and
is_a($bootstrap, Bootstrap::class, true)
) {
$bootstrap::start(null);
$bootstrap::start(null, $configPath);
}
}
// 加载路由
// 模拟webman-framework加载路由
Route::load($configPath);
// 加载服务
// 模拟启动服务
$this->pushServer = new PushServer();
$this->apiServer = new ApiServer();
parent::setUp();
}
}
Loading

0 comments on commit d9d5214

Please sign in to comment.