1
0
Fork 0
mirror of https://codeberg.org/demostf/api.git synced 2026-06-03 18:04:08 +02:00

filter by backend

This commit is contained in:
Robin Appelman 2017-08-08 00:29:24 +02:00
commit df83a46e20
17 changed files with 265 additions and 38 deletions

View file

@ -19,6 +19,8 @@ use Demostf\API\Providers\PlayerProvider;
use Demostf\API\Providers\UploadProvider; use Demostf\API\Providers\UploadProvider;
use Demostf\API\Providers\UserProvider; use Demostf\API\Providers\UserProvider;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
use flight\net\Request;
use flight\net\Response;
use RandomLib\Generator; use RandomLib\Generator;
class Container { class Container {
@ -30,8 +32,12 @@ class Container {
private $storeUrl; private $storeUrl;
private $apiRoot; private $apiRoot;
private $editKey; private $editKey;
private $request;
private $response;
public function __construct( public function __construct(
Request $request,
Response $response,
Connection $connection, Connection $connection,
Generator $generator, Generator $generator,
string $baseUrl, string $baseUrl,
@ -41,6 +47,8 @@ class Container {
string $apiRoot, string $apiRoot,
string $editKey string $editKey
) { ) {
$this->request = $request;
$this->response = $response;
$this->connection = $connection; $this->connection = $connection;
$this->generator = $generator; $this->generator = $generator;
$this->baseUrl = $baseUrl; $this->baseUrl = $baseUrl;
@ -129,4 +137,12 @@ class Container {
public function getConnection(): Connection { public function getConnection(): Connection {
return $this->connection; return $this->connection;
} }
public function getRequest(): Request {
return $this->request;
}
public function getResponse(): Response {
return $this->response;
}
} }

View file

@ -7,6 +7,8 @@ namespace Demostf\API\Controllers;
use Ehesp\SteamLogin\SteamLogin; use Ehesp\SteamLogin\SteamLogin;
use Demostf\API\Providers\AuthProvider; use Demostf\API\Providers\AuthProvider;
use Demostf\API\Providers\UserProvider; use Demostf\API\Providers\UserProvider;
use flight\net\Request;
use flight\net\Response;
class AuthController extends BaseController { class AuthController extends BaseController {
/** /**
@ -24,7 +26,15 @@ class AuthController extends BaseController {
private $apiRoot; private $apiRoot;
public function __construct(UserProvider $userProvider, AuthProvider $authProvider, string $host, string $apiRoot) { public function __construct(
Request $request,
Response $response,
UserProvider $userProvider,
AuthProvider $authProvider,
string $host,
string $apiRoot
) {
parent::__construct($request, $response);
$this->userProvider = $userProvider; $this->userProvider = $userProvider;
$this->authProvider = $authProvider; $this->authProvider = $authProvider;
$this->host = $host; $this->host = $host;

View file

@ -4,22 +4,37 @@ declare(strict_types=1);
namespace Demostf\API\Controllers; namespace Demostf\API\Controllers;
class BaseController { use flight\net\Request;
protected function query($name, $default) { use flight\net\Response;
$request = \Flight::request();
return isset($request->query[$name]) ? $request->query[$name] : $default; class BaseController {
private $request;
private $response;
public function __construct(Request $request, Response $response) {
$this->request = $request;
$this->response = $response;
}
protected function query($name, $default) {
return isset($this->request->query[$name]) ? $this->request->query[$name] : $default;
} }
protected function file($name) { protected function file($name) {
$request = \Flight::request(); return $this->request->files[$name];
return $request->files[$name];
} }
protected function post($name, $default = null) { protected function post($name, $default = null) {
$request = \Flight::request(); return isset($this->request->data[$name]) ? $this->request->data[$name] : $default;
}
return isset($request->data[$name]) ? $request->data[$name] : $default; protected function json($data, $code = 200, $encode = true, $charset = 'utf-8', $option = 0) {
$json = ($encode) ? json_encode($data, $option) : $data;
$this->response
->status($code)
->header('Content-Type', 'application/json; charset=' . $charset)
->write($json)
->send();
} }
} }

View file

@ -7,6 +7,8 @@ namespace Demostf\API\Controllers;
use Demostf\API\Providers\ChatProvider; use Demostf\API\Providers\ChatProvider;
use Demostf\API\Providers\DemoListProvider; use Demostf\API\Providers\DemoListProvider;
use Demostf\API\Providers\DemoProvider; use Demostf\API\Providers\DemoProvider;
use flight\net\Request;
use flight\net\Response;
class DemoController extends BaseController { class DemoController extends BaseController {
/** @var DemoProvider */ /** @var DemoProvider */
@ -20,11 +22,14 @@ class DemoController extends BaseController {
private $editKey; private $editKey;
public function __construct( public function __construct(
Request $request,
Response $response,
DemoProvider $demoProvider, DemoProvider $demoProvider,
ChatProvider $chatProvider, ChatProvider $chatProvider,
DemoListProvider $demoListProvider, DemoListProvider $demoListProvider,
string $editKey string $editKey
) { ) {
parent::__construct($request, $response);
$this->demoProvider = $demoProvider; $this->demoProvider = $demoProvider;
$this->chatProvider = $chatProvider; $this->chatProvider = $chatProvider;
$this->demoListProvider = $demoListProvider; $this->demoListProvider = $demoListProvider;
@ -35,17 +40,21 @@ class DemoController extends BaseController {
* @param string $id * @param string $id
*/ */
public function get($id) { public function get($id) {
\Flight::json($this->demoProvider->get(intval($id, 10))); $this->json($this->demoProvider->get(intval($id, 10)));
} }
protected function getFilter() { protected function getFilter() {
$map = $this->query('map', ''); $map = $this->query('map', '');
$players = $this->query('players', ''); $players = $this->query('players', '');
$type = $this->query('type', ''); $type = $this->query('type', '');
$backend = $this->query('backend', '');
$filter = []; $filter = [];
if ($map) { if ($map) {
$filter['map'] = $map; $filter['map'] = $map;
} }
if ($backend) {
$filter['backend'] = $backend;
}
if ($players) { if ($players) {
if (!is_array($players)) { if (!is_array($players)) {
$players = explode(',', $players); $players = explode(',', $players);
@ -71,23 +80,23 @@ class DemoController extends BaseController {
public function listDemos() { public function listDemos() {
$page = $this->query('page', 1); $page = $this->query('page', 1);
$order = $this->query('order', 'DESC') === 'ASC' ? 'ASC' : 'DESC'; $order = $this->query('order', 'DESC') === 'ASC' ? 'ASC' : 'DESC';
\Flight::json($this->demoListProvider->listDemos((int)$page, $this->getFilter(), $order)); $this->json($this->demoListProvider->listDemos((int) $page, $this->getFilter(), $order));
} }
public function listProfile($steamId) { public function listProfile($steamId) {
$page = $this->query('page', 1); $page = $this->query('page', 1);
$where = $this->getFilter(); $where = $this->getFilter();
$where['players'][] = $steamId; $where['players'][] = $steamId;
\Flight::json($this->demoListProvider->listProfile((int)$page, $where)); $this->json($this->demoListProvider->listProfile((int) $page, $where));
} }
public function listUploads($steamId) { public function listUploads($steamId) {
$page = $this->query('page', 1); $page = $this->query('page', 1);
\Flight::json($this->demoListProvider->listUploads($steamId, (int)$page, $this->getFilter())); $this->json($this->demoListProvider->listUploads($steamId, (int) $page, $this->getFilter()));
} }
public function chat($demoId) { public function chat($demoId) {
\Flight::json($this->chatProvider->getChat((int)$demoId)); $this->json($this->chatProvider->getChat((int) $demoId));
} }
public function setDemoUrl($id) { public function setDemoUrl($id) {

View file

@ -5,12 +5,15 @@ declare(strict_types=1);
namespace Demostf\API\Controllers; namespace Demostf\API\Controllers;
use Demostf\API\Providers\InfoProvider; use Demostf\API\Providers\InfoProvider;
use flight\net\Request;
use flight\net\Response;
class InfoController extends BaseController { class InfoController extends BaseController {
/** @var InfoProvider */ /** @var InfoProvider */
private $infoProvider; private $infoProvider;
public function __construct(InfoProvider $infoProvider) { public function __construct(Request $request, Response $response, InfoProvider $infoProvider) {
parent::__construct($request, $response);
$this->infoProvider = $infoProvider; $this->infoProvider = $infoProvider;
} }

View file

@ -5,11 +5,14 @@ declare(strict_types=1);
namespace Demostf\API\Controllers; namespace Demostf\API\Controllers;
use Demostf\API\Providers\UploadProvider; use Demostf\API\Providers\UploadProvider;
use flight\net\Request;
use flight\net\Response;
class UploadController extends BaseController { class UploadController extends BaseController {
private $uploadProvider; private $uploadProvider;
public function __construct(UploadProvider $uploadProvider) { public function __construct(Request $request, Response $response, UploadProvider $uploadProvider) {
parent::__construct($request, $response);
$this->uploadProvider = $uploadProvider; $this->uploadProvider = $uploadProvider;
} }

View file

@ -5,6 +5,8 @@ declare(strict_types=1);
namespace Demostf\API\Controllers; namespace Demostf\API\Controllers;
use Demostf\API\Providers\UserProvider; use Demostf\API\Providers\UserProvider;
use flight\net\Request;
use flight\net\Response;
class UserController extends BaseController { class UserController extends BaseController {
/** /**
@ -12,7 +14,8 @@ class UserController extends BaseController {
*/ */
private $userProvider; private $userProvider;
public function __construct(UserProvider $userProvider) { public function __construct(Request $request, Response $response, UserProvider $userProvider) {
parent::__construct($request, $response);
$this->userProvider = $userProvider; $this->userProvider = $userProvider;
} }

View file

@ -23,10 +23,11 @@ class BaseProvider {
/** /**
* BaseProvider constructor. * BaseProvider constructor.
* @param Connection $connection *
* @param connection $connection
* *
* The DBAL connection used will always be a PDO * The DBAL connection used will always be a PDO
* but phan isn't aware of this. * but phan isn't aware of this
* *
* @suppress PhanTypeMismatchArgument * @suppress PhanTypeMismatchArgument
*/ */

View file

@ -70,6 +70,10 @@ class DemoListProvider extends BaseProvider {
$query->where($query->expr()->in('uploader', $query->where($query->expr()->in('uploader',
$query->createNamedParameter($where['uploader'], \PDO::PARAM_INT))); $query->createNamedParameter($where['uploader'], \PDO::PARAM_INT)));
} }
if (isset($where['backend'])) {
$query->where($query->expr()->eq('backend',
$query->createNamedParameter($where['backend'])));
}
$query->orderBy('d.id', $order) $query->orderBy('d.id', $order)
->setMaxResults(50) ->setMaxResults(50)
->setFirstResult($offset); ->setFirstResult($offset);

View file

@ -10,19 +10,25 @@ use Flight;
$container = require __DIR__ . '/init.php'; $container = require __DIR__ . '/init.php';
$demoController = new Controllers\DemoController( $demoController = new Controllers\DemoController(
$container->getRequest(),
$container->getResponse(),
$container->getDemoProvider(), $container->getDemoProvider(),
$container->getChatProvider(), $container->getChatProvider(),
$container->getDemoListProvider(), $container->getDemoListProvider(),
$container->getEditKey() $container->getEditKey()
); );
$authController = new Controllers\AuthController( $authController = new Controllers\AuthController(
$container->getRequest(),
$container->getResponse(),
$container->getUserProvider(), $container->getUserProvider(),
$container->getAuthProvider(), $container->getAuthProvider(),
$container->getBaseUrl(), $container->getBaseUrl(),
$container->getApiRoot() $container->getApiRoot()
); );
$userController = new Controllers\UserController($container->getUserProvider()); $userController = new Controllers\UserController($container->getRequest(), $container->getResponse(),
$infoController = new Controllers\InfoController($container->getInfoProvider()); $container->getUserProvider());
$infoController = new Controllers\InfoController($container->getRequest(), $container->getResponse(),
$container->getInfoProvider());
Flight::route('/*', function () { Flight::route('/*', function () {
header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Origin: *');

View file

@ -33,6 +33,8 @@ $factory = new \RandomLib\Factory();
$generator = $factory->getMediumStrengthGenerator(); $generator = $factory->getMediumStrengthGenerator();
$container = new Container( $container = new Container(
Flight::request(),
Flight::response(),
$db, $db,
$generator, $generator,
'https://' . $host, 'https://' . $host,

View file

@ -4,13 +4,16 @@ declare(strict_types=1);
namespace Demostf\API; namespace Demostf\API;
use Demostf\API\Providers\Container;
use Flight; use Flight;
/** @var Container $container */ /** @var Container $container */
$container = require __DIR__ . '/init.php'; $container = require __DIR__ . '/init.php';
$uploadController = new Controllers\UploadController($container->getUploadProvider()); $uploadController = new Controllers\UploadController(
$container->getRequest(),
$container->getResponse(),
$container->getUploadProvider()
);
Flight::route('/*', function () { Flight::route('/*', function () {
header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Origin: *');

View file

@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace Demostf\API\Test\Controllers;
use Demostf\API\Test\TestCase;
use flight\net\Request;
use flight\net\Response;
use flight\util\Collection;
abstract class ControllerTest extends TestCase {
/** @var string $responseData */
private $responseData;
protected function getRequest(array $get = [], array $post = [], array $files = []): Request {
/** @var Request $mock */
$mock = $this->getMockBuilder(Request::class)
->disableOriginalConstructor()
->setMethods([])
->getMock();
$mock->query = new Collection($get);
$mock->data = new Collection($post);
$mock->files = new Collection($files);
return $mock;
}
protected function getResponse() {
/** @var Response|\PHPUnit_Framework_MockObject_MockObject $mock */
$mock = $this->getMockBuilder(Response::class)
->disableOriginalConstructor()
->setMethods(['send'])
->getMock();
$mock->expects($this->any())
->method('send')
->willReturnCallback(function () use ($mock) {
$reflection = new \ReflectionClass($mock);
$bodyProperty = $reflection->getProperty('body');
$bodyProperty->setAccessible(true);
$this->responseData = $bodyProperty->getValue($mock);
});
return $mock;
}
protected function getResponseData() {
return $this->responseData;
}
}

View file

@ -0,0 +1,84 @@
<?php
declare(strict_types=1);
namespace Demostf\API\Test\Controllers;
use Demostf\API\Controllers\DemoController;
use Demostf\API\Providers\ChatProvider;
use Demostf\API\Providers\DemoListProvider;
use Demostf\API\Providers\DemoProvider;
class DemoControllerTest extends ControllerTest {
/** @var DemoProvider|\PHPUnit_Framework_MockObject_MockObject $demoProvider */
private $demoProvider;
/** @var ChatProvider|\PHPUnit_Framework_MockObject_MockObject $chatProvider */
private $chatProvider;
/** @var DemoListProvider|\PHPUnit_Framework_MockObject_MockObject $demoListProvider */
private $demoListProvider;
public function setUp() {
parent::setUp();
$this->demoProvider = $this->createMock(DemoProvider::class);
$this->chatProvider = $this->createMock(ChatProvider::class);
$this->demoListProvider = $this->createMock(DemoListProvider::class);
}
public function testGetBasicList() {
$controller = new DemoController(
$this->getRequest(),
$this->getResponse(),
$this->demoProvider,
$this->chatProvider,
$this->demoListProvider,
''
);
$this->demoListProvider->expects($this->once())
->method('listDemos')
->with(1, [], 'DESC')
->willReturn(['dummy']);
$controller->listDemos();
$this->assertEquals('["dummy"]', $this->getResponseData());
}
public function testGetListPageASC() {
$controller = new DemoController(
$this->getRequest(['page' => '3', 'order' => 'ASC']),
$this->getResponse(),
$this->demoProvider,
$this->chatProvider,
$this->demoListProvider,
''
);
$this->demoListProvider->expects($this->once())
->method('listDemos')
->with(3, [], 'ASC')
->willReturn(['dummy']);
$controller->listDemos();
$this->assertEquals('["dummy"]', $this->getResponseData());
}
public function testListFilterBackend() {
$controller = new DemoController(
$this->getRequest(['backend' => 'foo']),
$this->getResponse(),
$this->demoProvider,
$this->chatProvider,
$this->demoListProvider,
''
);
$this->demoListProvider->expects($this->once())
->method('listDemos')
->with(1, ['backend' => 'foo'], 'DESC')
->willReturn(['dummy']);
$controller->listDemos();
$this->assertEquals('["dummy"]', $this->getResponseData());
}
}

View file

@ -153,13 +153,28 @@ class DemoListProviderTest extends TestCase {
$this->assertEquals($id2, $list[0]->getId()); $this->assertEquals($id2, $list[0]->getId());
$this->assertEquals($id1, $list[1]->getId()); $this->assertEquals($id1, $list[1]->getId());
$list = $this->demoListProvider->listDemos(1, ['players' => [$steamId1->getSteamId64(), $steamId3->getSteamId64()]]); $list = $this->demoListProvider->listDemos(1,
['players' => [$steamId1->getSteamId64(), $steamId3->getSteamId64()]]);
$this->assertCount(1, $list); $this->assertCount(1, $list);
$this->assertEquals($id2, $list[0]->getId()); $this->assertEquals($id2, $list[0]->getId());
$list = $this->demoListProvider->listDemos(1, ['players' => [$steamId2->getSteamId64(), $steamId3->getSteamId64()]]); $list = $this->demoListProvider->listDemos(1,
['players' => [$steamId2->getSteamId64(), $steamId3->getSteamId64()]]);
$this->assertCount(0, $list); $this->assertCount(0, $list);
} }
public function testByUploaderFilterBackend() {
$steamId = $this->getSteamId('12345', 'bar');
$this->userProvider->store($steamId);
$userId = $this->userProvider->get($steamId->getSteamId64())->getId();
$id1 = $this->demoProvider->storeDemo($this->getDemo($userId, 'map1', 12), 'foo1', 'bar');
$id2 = $this->demoProvider->storeDemo($this->getDemo($userId, 'map2', 18), 'foo1', 'bar');
$id3 = $this->demoProvider->storeDemo($this->getDemo($userId + 1, 'map1', 12), 'foo2', 'bar');
$list = $this->demoListProvider->listUploads($steamId->getSteamId64(), 1, ['backend' => 'foo2']);
$this->assertEquals($id3, $list[0]->getId());
}
} }