Refactor routing/controller layer for better separation of concerns
This commit is contained in:
parent
31ace0ec11
commit
04920a86a2
@ -6,7 +6,7 @@ require_once __DIR__ . '/../vendor/autoload.php';
|
||||
use ActivityPub\Auth\AuthListener;
|
||||
use ActivityPub\Auth\SignatureListener;
|
||||
use ActivityPub\Config\ActivityPubModule;
|
||||
use ActivityPub\Http\ControllerResolver;
|
||||
use ActivityPub\Http\Router;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\Tools\SchemaTool;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@ -14,6 +14,7 @@ use Symfony\Component\HttpKernel\HttpKernel;
|
||||
use Symfony\Component\EventDispatcher;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
|
||||
use Symfony\Component\HttpKernel\EventListener\ExceptionListener;
|
||||
|
||||
class ActivityPub
|
||||
@ -49,11 +50,12 @@ class ActivityPub
|
||||
}
|
||||
|
||||
$dispatcher = $this->module->get( EventDispatcher::class );
|
||||
$dispatcher->addSubscriber( $this->module->get( Router::class ) );
|
||||
$dispatcher->addSubscriber( $this->module->get( AuthListener::class ) );
|
||||
$dispatcher->addSubscriber( $this->module->get( SignatureListener::class ) );
|
||||
$dispatcher->addSubscriber( new ExceptionListener() );
|
||||
|
||||
$controllerResolver = $this->module->get( ControllerResolver::class );
|
||||
$controllerResolver = new ControllerResolver();
|
||||
$argumentResolver = new ArgumentResolver();
|
||||
|
||||
$kernel = new HttpKernel(
|
||||
|
@ -4,12 +4,11 @@ namespace ActivityPub\Config;
|
||||
use ActivityPub\Auth\AuthListener;
|
||||
use ActivityPub\Auth\AuthService;
|
||||
use ActivityPub\Auth\SignatureListener;
|
||||
use ActivityPub\Controllers\GetObjectController;
|
||||
use ActivityPub\Controllers\InboxController;
|
||||
use ActivityPub\Controllers\OutboxController;
|
||||
use ActivityPub\Controllers\GetController;
|
||||
use ActivityPub\Controllers\PostController;
|
||||
use ActivityPub\Crypto\HttpSignatureService;
|
||||
use ActivityPub\Database\PrefixNamingStrategy;
|
||||
use ActivityPub\Http\ControllerResolver;
|
||||
use ActivityPub\Http\Router;
|
||||
use ActivityPub\Objects\ContextProvider;
|
||||
use ActivityPub\Objects\CollectionsService;
|
||||
use ActivityPub\Objects\IdProvider;
|
||||
@ -104,22 +103,18 @@ class ActivityPubModule
|
||||
->addArgument( new Reference( ObjectsService::class ) )
|
||||
->addArgument( new Reference( RandomProvider::class ) );
|
||||
|
||||
$this->injector->register( GetObjectController::class, GetObjectController::class )
|
||||
$this->injector->register( GetController::class, GetController::class )
|
||||
->addArgument( new Reference( ObjectsService::class ) )
|
||||
->addArgument( new Reference( CollectionsService::class ) )
|
||||
->addArgument( new Reference( AuthService::class ) );
|
||||
|
||||
$this->injector->register( InboxController::class, InboxController::class )
|
||||
->addArgument( new Reference( EventDispatcher::class ) );
|
||||
$this->injector->register( PostController::class, PostController::class )
|
||||
->addArgument( new Reference( EventDispatcher::class ) )
|
||||
->addArgument( new Reference( ObjectsService::class ) );
|
||||
|
||||
$this->injector->register( OutboxController::class, OutboxController::class )
|
||||
->addArgument( new Reference( EventDispatcher::class ) );
|
||||
|
||||
$this->injector->register( ControllerResolver::class, ControllerResolver::class )
|
||||
->addArgument( new Reference( ObjectsService::class ) )
|
||||
->addArgument( new Reference( GetObjectController::class ) )
|
||||
->addArgument( new Reference( InboxController::class ) )
|
||||
->addArgument( new Reference( OutboxController::class ) );
|
||||
$this->injector->register( Router::class, Router::class )
|
||||
->addArgument( new Reference( GetController::class ) )
|
||||
->addArgument( new Reference( PostController::class ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -11,9 +11,9 @@ use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* The GetObjectController is responsible for rendering ActivityPub objects as JSON
|
||||
* The GetController is responsible for rendering ActivityPub objects as JSON
|
||||
*/
|
||||
class GetObjectController
|
||||
class GetController
|
||||
{
|
||||
|
||||
/**
|
@ -1,51 +0,0 @@
|
||||
<?php
|
||||
namespace ActivityPub\Controllers;
|
||||
|
||||
use ActivityPub\Activities\InboxActivityEvent;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* The InboxController handles POST requests to an inbox
|
||||
*/
|
||||
class InboxController
|
||||
{
|
||||
private $eventDispatcher;
|
||||
|
||||
public function __construct( EventDispatcher $EventDispatcher )
|
||||
{
|
||||
$this->eventDispatcher = $EventDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the inbox request and returns a proper Response
|
||||
*
|
||||
* @param Request $request The request
|
||||
* @return Response
|
||||
*/
|
||||
public function handle( Request $request )
|
||||
{
|
||||
if ( ! $request->attributes->has( 'actor' ) ) {
|
||||
throw new UnauthorizedHttpException();
|
||||
}
|
||||
$actor = $request->attributes->get( 'actor' );
|
||||
$inboxId = $this->getUriWithoutQuery( $request );
|
||||
if ( ! $actor->hasField( 'inbox' ) || $actor['inbox']['id'] !== $inboxId ) {
|
||||
throw new UnauthorizedHttpException();
|
||||
}
|
||||
$activity = $request->attributes->get( 'activity' );
|
||||
$event = new InboxActivityEvent( $activity, $actor, $request );
|
||||
$this->eventDispatcher->dispatch( InboxActivityEvent::NAME, $event );
|
||||
}
|
||||
|
||||
private function getUriWithoutQuery( Request $request )
|
||||
{
|
||||
$uri = $request->getUri();
|
||||
$queryPos = strpos( $uri, '?' );
|
||||
if ( $queryPos !== false ) {
|
||||
$uri = substr( $uri, 0, $queryPos );
|
||||
}
|
||||
return $uri;
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,52 +0,0 @@
|
||||
<?php
|
||||
namespace ActivityPub\Controllers;
|
||||
|
||||
use ActivityPub\Activities\OutboxActivityEvent;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
|
||||
|
||||
class OutboxController
|
||||
{
|
||||
/**
|
||||
* @var EventDispatcher
|
||||
*/
|
||||
private $eventDispatcher;
|
||||
|
||||
public function __construct( EventDispatcher $eventDispatcher )
|
||||
{
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the outbox request and returns a proper response
|
||||
*
|
||||
* @param Request $request The incoming request
|
||||
* @return Response
|
||||
*/
|
||||
public function handle( Request $request )
|
||||
{
|
||||
if ( ! $request->attributes->has( 'actor' ) ) {
|
||||
throw new UnauthorizedHttpException();
|
||||
}
|
||||
$actor = $request->attributes->get( 'actor' );
|
||||
$outboxId = $this->getUriWithoutQuery( $request );
|
||||
if ( ! $actor->hasField( 'outbox' ) || $actor['outbox']['id'] !== $outboxId ) {
|
||||
throw new UnauthorizedHttpException();
|
||||
}
|
||||
$activity = $request->attributes->get( 'activity' );
|
||||
$event = new OutboxActivityEvent( $activity, $actor, $request );
|
||||
$this->eventDispatcher->dispatch( OutboxActivityEvent::NAME, $event );
|
||||
}
|
||||
|
||||
private function getUriWithoutQuery( Request $request )
|
||||
{
|
||||
$uri = $request->getUri();
|
||||
$queryPos = strpos( $uri, '?' );
|
||||
if ( $queryPos !== false ) {
|
||||
$uri = substr( $uri, 0, $queryPos );
|
||||
}
|
||||
return $uri;
|
||||
}
|
||||
}
|
||||
?>
|
111
src/Controllers/PostController.php
Normal file
111
src/Controllers/PostController.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
namespace ActivityPub\Controllers;
|
||||
|
||||
use ActivityPub\Activities\InboxActivityEvent;
|
||||
use ActivityPub\Activities\OutboxActivityEvent;
|
||||
use ActivityPub\Objects\ObjectsService;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
|
||||
|
||||
/**
|
||||
* The PostController is responsible for handling incoming ActivityPub POST requests
|
||||
*/
|
||||
class PostController
|
||||
{
|
||||
/**
|
||||
* @var EventDispatcher
|
||||
*/
|
||||
private $eventDispatcher;
|
||||
|
||||
/**
|
||||
* @var ObjectsService
|
||||
*/
|
||||
private $objectsService;
|
||||
|
||||
public function __construct( EventDispatcher $eventDispatcher,
|
||||
ObjectsService $objectsService )
|
||||
{
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
$this->objectsService = $objectsService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an incoming POST request
|
||||
*
|
||||
* Either dispatches an inbox/outbox activity event or throws the appropriate
|
||||
* HTTP error.
|
||||
* @param Request $request The request
|
||||
*/
|
||||
public function handle( Request $request )
|
||||
{
|
||||
$uri = $this->getUriWithoutQuery( $request );
|
||||
$object = $this->objectsService->dereference( $uri );
|
||||
if ( ! $object ) {
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
$actorWithInbox = $this->objectWithField( 'inbox', $uri );
|
||||
if ( $actorWithInbox ) {
|
||||
if ( ! $request->attributes->has( 'signed' ) ||
|
||||
! $this->authorized( $request, $actorWithInbox ) ) {
|
||||
throw new UnauthorizedHttpException();
|
||||
}
|
||||
$activity = json_decode( $request->getContent(), true );
|
||||
if ( ! $activity ) {
|
||||
throw new BadRequestHttpException();
|
||||
}
|
||||
$event = new InboxActivityEvent( $activity, $actorWithInbox, $request );
|
||||
$this->eventDispatcher->dispatch( InboxActivityEvent::NAME, $event );
|
||||
return;
|
||||
}
|
||||
$actorWithOutbox = $this->objectWithField( 'outbox', $uri );
|
||||
if ( $actorWithOutbox ) {
|
||||
if ( ! $this->authorized( $request, $actorWithOutbox ) ) {
|
||||
throw new UnauthorizedHttpException();
|
||||
}
|
||||
$activity = json_decode( $request->getContent(), true );
|
||||
if ( ! $activity ) {
|
||||
throw new BadRequestHttpException();
|
||||
}
|
||||
$event = new OutboxActivityEvent( $activity, $actorWithOutbox, $request );
|
||||
$this->eventDispatcher->dispatch( OutboxActivityEvent::NAME, $event );
|
||||
return;
|
||||
}
|
||||
throw new MethodNotAllowedHttpException( array( Request::METHOD_GET ) );
|
||||
}
|
||||
|
||||
private function authorized( Request $request, ActivityPubObject $activityActor )
|
||||
{
|
||||
if ( ! $request->attributes->has( 'actor' ) ) {
|
||||
return false;
|
||||
}
|
||||
$requestActor = $request->attributes->get( 'actor' );
|
||||
if ( $requestActor['id'] !== $activityActor['id'] ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function objectWithField( string $name, string $value )
|
||||
{
|
||||
$results = $this->objectsService->query( array( $name => $value ) );
|
||||
if ( count( $results ) === 0 ) {
|
||||
return false;
|
||||
}
|
||||
return $results[0];
|
||||
}
|
||||
|
||||
private function getUriWithoutQuery( Request $request )
|
||||
{
|
||||
$uri = $request->getUri();
|
||||
$queryPos = strpos( $uri, '?' );
|
||||
if ( $queryPos !== false ) {
|
||||
$uri = substr( $uri, 0, $queryPos );
|
||||
}
|
||||
return $uri;
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,93 +0,0 @@
|
||||
<?php
|
||||
namespace ActivityPub\Http;
|
||||
|
||||
use ActivityPub\Controllers\GetObjectController;
|
||||
use ActivityPub\Controllers\InboxController;
|
||||
use ActivityPub\Controllers\OutboxController;
|
||||
use ActivityPub\Objects\ObjectsService;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class ControllerResolver implements ControllerResolverInterface
|
||||
{
|
||||
private $objectsService;
|
||||
private $getObjectController;
|
||||
private $inboxController;
|
||||
private $outboxController;
|
||||
|
||||
public function __construct( ObjectsService $objectsService,
|
||||
GetObjectController $getObjectController,
|
||||
InboxController $inboxController,
|
||||
OutboxController $outboxController )
|
||||
{
|
||||
$this->objectsService = $objectsService;
|
||||
$this->getObjectController = $getObjectController;
|
||||
$this->inboxController = $inboxController;
|
||||
$this->outboxController = $outboxController;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if an object with a field named $name with value $value exists
|
||||
*
|
||||
* @param string $name The field name to look for
|
||||
* @param string $value The field value to look for
|
||||
* @return ActivityPubObject|bool The first result, or false if there are no results
|
||||
*/
|
||||
private function objectWithField( string $name, string $value )
|
||||
{
|
||||
$results = $this->objectsService->query( array( $name => $value ) );
|
||||
if ( count( $results ) === 0 ) {
|
||||
return false;
|
||||
}
|
||||
return $results[0];
|
||||
}
|
||||
|
||||
public function getController( Request $request )
|
||||
{
|
||||
if ( $request->getMethod() == Request::METHOD_GET ) {
|
||||
return array( $this->getObjectController, 'handle' );
|
||||
} else if ( $request->getMethod() == Request::METHOD_POST ) {
|
||||
$uri = $this->getUriWithoutQuery( $request );
|
||||
$actorWithInbox = $this->objectWithField( 'inbox', $uri );
|
||||
if ( $actorWithInbox ) {
|
||||
$activity = json_decode( $request->getContent(), true );
|
||||
if ( ! $activity || ! array_key_exists( 'type', $activity ) ) {
|
||||
throw new BadRequestHttpException( '"type" field not found' );
|
||||
}
|
||||
$request->attributes->set( 'activity', $activity );
|
||||
return array( $this->inboxController, 'handle' );
|
||||
} else {
|
||||
$actorWithOutbox = $this->objectWithField( 'outbox', $uri );
|
||||
if ( $actorWithOutbox ) {
|
||||
$activity = json_decode( $request->getContent(), true );
|
||||
if ( ! $activity || ! array_key_exists( 'type', $activity ) ) {
|
||||
throw new BadRequestHttpException( '"type" field not found' );
|
||||
}
|
||||
$request->attributes->set( 'activity', $activity );
|
||||
return array( $this->outboxController, 'handle' );
|
||||
} else {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new MethodNotAllowedHttpException( array(
|
||||
Request::METHOD_GET,
|
||||
Request::METHOD_POST,
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
private function getUriWithoutQuery( Request $request )
|
||||
{
|
||||
$uri = $request->getUri();
|
||||
$queryPos = strpos( $uri, '?' );
|
||||
if ( $queryPos !== false ) {
|
||||
$uri = substr( $uri, 0, $queryPos );
|
||||
}
|
||||
return $uri;
|
||||
}
|
||||
}
|
||||
?>
|
60
src/Http/Router.php
Normal file
60
src/Http/Router.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
namespace ActivityPub\Http;
|
||||
|
||||
use ActivityPub\Controllers\GetController;
|
||||
use ActivityPub\Controllers\PostController;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
class Router implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* @var GetController
|
||||
*/
|
||||
private $getController;
|
||||
|
||||
/**
|
||||
* @var PostController
|
||||
*/
|
||||
private $postController;
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
KernelEvents::REQUEST => 'route',
|
||||
);
|
||||
}
|
||||
|
||||
public function __construct( GetController $getController,
|
||||
PostController $postController )
|
||||
{
|
||||
$this->getController = $getController;
|
||||
$this->postController = $postController;
|
||||
}
|
||||
/**
|
||||
* Routes the request by setting the _controller attribute
|
||||
*
|
||||
* @param GetResponseEvent $event The request event
|
||||
*/
|
||||
public function route( GetResponseEvent $event )
|
||||
{
|
||||
$request = $event->getRequest();
|
||||
if ( $request->getMethod() === Request::METHOD_GET ) {
|
||||
$request->attributes->set(
|
||||
'_controller', array( $this->getController, 'handle' )
|
||||
);
|
||||
} else if ( $request->getMethod() === Request::METHOD_POST ) {
|
||||
$request->attributes->set(
|
||||
'_controller', array( $this->postController, 'handle' )
|
||||
);
|
||||
} else {
|
||||
throw new MethodNotAllowedHttpException( array(
|
||||
Request::METHOD_GET, Request::METHOD_POST
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
@ -2,7 +2,7 @@
|
||||
namespace ActivityPub\Test\Config;
|
||||
|
||||
use ActivityPub\Config\ActivityPubModule;
|
||||
use ActivityPub\Http\ControllerResolver;
|
||||
use ActivityPub\Http\Router;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
@ -27,10 +27,9 @@ class ActivityPubModuleTest extends TestCase
|
||||
$this->assertNotNull( $entityManager );
|
||||
$this->assertInstanceOf( EntityManager::class, $entityManager );
|
||||
|
||||
$controllerResolver = $this->module->get( ControllerResolver::class );
|
||||
$this->assertNotNull( $controllerResolver );
|
||||
$this->assertInstanceOf( ControllerResolver::class, $controllerResolver );
|
||||
|
||||
$router = $this->module->get( Router::class );
|
||||
$this->assertNotNull( $router );
|
||||
$this->assertInstanceOf( Router::class, $router );
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@ -2,7 +2,7 @@
|
||||
namespace ActivityPub\Test\Controllers;
|
||||
|
||||
use ActivityPub\Auth\AuthService;
|
||||
use ActivityPub\Controllers\GetObjectController;
|
||||
use ActivityPub\Controllers\GetController;
|
||||
use ActivityPub\Entities\ActivityPubObject;
|
||||
use ActivityPub\Entities\Field;
|
||||
use ActivityPub\Objects\ContextProvider;
|
||||
@ -14,7 +14,7 @@ use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class GetObjectControllerTest extends TestCase
|
||||
class GetControllerTest extends TestCase
|
||||
{
|
||||
const OBJECTS = array(
|
||||
'https://example.com/objects/1' => array(
|
||||
@ -51,7 +51,7 @@ class GetObjectControllerTest extends TestCase
|
||||
),
|
||||
);
|
||||
|
||||
private $getObjectController;
|
||||
private $getController;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
@ -66,7 +66,7 @@ class GetObjectControllerTest extends TestCase
|
||||
$authService = new AuthService();
|
||||
$contextProvider = new ContextProvider();
|
||||
$collectionsService = new CollectionsService( 4, $authService, $contextProvider );
|
||||
$this->getObjectController = new GetObjectController(
|
||||
$this->getController = new GetController(
|
||||
$objectsService, $collectionsService, $authService
|
||||
);
|
||||
}
|
||||
@ -74,7 +74,7 @@ class GetObjectControllerTest extends TestCase
|
||||
public function testItRendersPersistedObject()
|
||||
{
|
||||
$request = Request::create( 'https://example.com/objects/1' );
|
||||
$response = $this->getObjectController->handle( $request );
|
||||
$response = $this->getController->handle( $request );
|
||||
$this->assertNotNull( $response );
|
||||
$this->assertEquals(
|
||||
json_encode( self::OBJECTS['https://example.com/objects/1'] ),
|
||||
@ -87,21 +87,21 @@ class GetObjectControllerTest extends TestCase
|
||||
{
|
||||
$request = Request::create( 'https://example.com/objects/notreal' );
|
||||
$this->expectException( NotFoundHttpException::class );
|
||||
$this->getObjectController->handle( $request );
|
||||
$this->getController->handle( $request );
|
||||
}
|
||||
|
||||
public function testItDeniesAccess()
|
||||
{
|
||||
$request = Request::create( 'https://example.com/objects/2' );
|
||||
$this->expectException( UnauthorizedHttpException::class );
|
||||
$this->getObjectController->handle( $request );
|
||||
$this->getController->handle( $request );
|
||||
}
|
||||
|
||||
public function testItAllowsAccessToAuthedActor()
|
||||
{
|
||||
$request = Request::create( 'https://example.com/objects/2' );
|
||||
$request->attributes->set( 'actor', 'https://example.com/actor/1' );
|
||||
$response = $this->getObjectController->handle( $request );
|
||||
$response = $this->getController->handle( $request );
|
||||
$this->assertNotNull( $response );
|
||||
$this->assertEquals(
|
||||
json_encode( self::OBJECTS['https://example.com/objects/2'] ),
|
||||
@ -114,7 +114,7 @@ class GetObjectControllerTest extends TestCase
|
||||
{
|
||||
$request = Request::create( 'https://example.com/objects/2' );
|
||||
$request->attributes->set( 'actor', 'https://example.com/actor/2' );
|
||||
$response = $this->getObjectController->handle( $request );
|
||||
$response = $this->getController->handle( $request );
|
||||
$this->assertNotNull( $response );
|
||||
$this->assertEquals(
|
||||
json_encode( self::OBJECTS['https://example.com/objects/2'] ),
|
||||
@ -126,7 +126,7 @@ class GetObjectControllerTest extends TestCase
|
||||
public function testItAllowsAccessToNoAudienceObject()
|
||||
{
|
||||
$request = Request::create( 'https://example.com/objects/3' );
|
||||
$response = $this->getObjectController->handle( $request );
|
||||
$response = $this->getController->handle( $request );
|
||||
$this->assertNotNull( $response );
|
||||
$this->assertEquals(
|
||||
json_encode( self::OBJECTS['https://example.com/objects/3'] ),
|
||||
@ -138,7 +138,7 @@ class GetObjectControllerTest extends TestCase
|
||||
public function testItDisregardsQueryParams()
|
||||
{
|
||||
$request = Request::create( 'https://example.com/objects/1?foo=bar&baz=qux' );
|
||||
$response = $this->getObjectController->handle( $request );
|
||||
$response = $this->getController->handle( $request );
|
||||
$this->assertNotNull( $response );
|
||||
$this->assertEquals(
|
||||
json_encode( self::OBJECTS['https://example.com/objects/1'] ),
|
@ -1,14 +0,0 @@
|
||||
<?php
|
||||
namespace ActivityPub\Test\Controllers;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class InboxControllerTest extends TestCase
|
||||
{
|
||||
public function testInboxController()
|
||||
{
|
||||
// TODO implement me
|
||||
$this->assertTrue( false );
|
||||
}
|
||||
}
|
||||
?>
|
@ -3,7 +3,7 @@ namespace ActivityPub\Test\Controllers;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class OutboxControllerTest extends TestCase
|
||||
class PostControllerTest extends TestCase
|
||||
{
|
||||
public function testOutboxController()
|
||||
{
|
@ -1,130 +0,0 @@
|
||||
<?php
|
||||
namespace ActivityPub\Test\Http;
|
||||
|
||||
use ActivityPub\Controllers\Inbox\DefaultInboxController;
|
||||
use ActivityPub\Controllers\Outbox\DefaultOutboxController;
|
||||
use ActivityPub\Controllers\GetObjectController;
|
||||
use ActivityPub\Controllers\InboxController;
|
||||
use ActivityPub\Controllers\OutboxController;
|
||||
use ActivityPub\Http\ControllerResolver;
|
||||
use ActivityPub\Objects\ObjectsService;
|
||||
use ActivityPub\Test\TestUtils\TestUtils;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class ControllerResolverTest extends TestCase
|
||||
{
|
||||
const INBOX_URI = 'https://example.com/inbox';
|
||||
const OUTBOX_URI = 'https://example.com/outbox';
|
||||
|
||||
private $controllerResolver;
|
||||
private $getObjectController;
|
||||
private $inboxController;
|
||||
private $outboxController;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$objectsService = $this->createMock( ObjectsService::class );
|
||||
$objectsService->method( 'query' )->will(
|
||||
$this->returnCallback( function ( $query ) {
|
||||
if ( array_key_exists( 'inbox', $query ) &&
|
||||
$query['inbox'] == self::INBOX_URI ) {
|
||||
return array( TestUtils::objectFromArray( array(
|
||||
'id' => 'https://example.com/actor/1',
|
||||
'inbox' => array(
|
||||
'id' => 'https://example.com/actor/1/inbox',
|
||||
),
|
||||
) ) );
|
||||
}
|
||||
if ( array_key_exists( 'outbox', $query ) &&
|
||||
$query['outbox'] == self::OUTBOX_URI ) {
|
||||
return array( TestUtils::objectFromArray( array(
|
||||
'id' => 'https://example.com/actor/1',
|
||||
'outbox' => array(
|
||||
'id' => 'https://example.com/actor/1/outbox',
|
||||
),
|
||||
) ) );
|
||||
}
|
||||
return array();
|
||||
})
|
||||
);
|
||||
$this->getObjectController = $this->createMock( GetObjectController::class );
|
||||
$this->inboxController = $this->createMock( InboxController::class );
|
||||
$this->outboxController = $this->createMock( OutboxController::class );
|
||||
$this->controllerResolver = new ControllerResolver(
|
||||
$objectsService,
|
||||
$this->getObjectController,
|
||||
$this->inboxController,
|
||||
$this->outboxController
|
||||
);
|
||||
}
|
||||
|
||||
private function createRequestWithBody( $uri, $method, $body )
|
||||
{
|
||||
$json = json_encode( $body );
|
||||
return Request::create($uri, $method, array(), array(), array(), array(), $json);
|
||||
}
|
||||
|
||||
public function testItReturnsGetObjectController()
|
||||
{
|
||||
$request = Request::create( 'https://example.com/object', Request::METHOD_GET );
|
||||
$controller = $this->controllerResolver->getController( $request );
|
||||
$this->assertIsCallable( $controller );
|
||||
$this->assertEquals( array( $this->getObjectController, 'handle' ), $controller );
|
||||
}
|
||||
|
||||
public function testItChecksForType()
|
||||
{
|
||||
$request = Request::create( 'https://example.com/inbox', Request::METHOD_POST );
|
||||
$this->expectException( BadRequestHttpException::class );
|
||||
$controller = $this->controllerResolver->getController( $request );
|
||||
}
|
||||
|
||||
public function testItReturnsInboxController()
|
||||
{
|
||||
$request = $this->createRequestWithBody(
|
||||
'https://example.com/inbox', Request::METHOD_POST, array( 'type' => 'Foo' )
|
||||
);
|
||||
$controller = $this->controllerResolver->getController( $request );
|
||||
$this->assertTrue( $request->attributes->has( 'activity' ) );
|
||||
$this->assertEquals(
|
||||
array( 'type' => 'Foo' ), $request->attributes->get( 'activity' )
|
||||
);
|
||||
$this->assertEquals( array( $this->inboxController, 'handle' ), $controller );
|
||||
}
|
||||
|
||||
public function testItReturnsOutboxController()
|
||||
{
|
||||
$request = $this->createRequestWithBody(
|
||||
'https://example.com/outbox', Request::METHOD_POST, array( 'type' => 'Foo' )
|
||||
);
|
||||
$controller = $this->controllerResolver->getController( $request );
|
||||
$this->assertTrue( $request->attributes->has( 'activity' ) );
|
||||
$this->assertEquals(
|
||||
array( 'type' => 'Foo' ), $request->attributes->get( 'activity' )
|
||||
);
|
||||
$this->assertEquals( array( $this->outboxController, 'handle' ), $controller );
|
||||
}
|
||||
|
||||
public function testItDisallowsPostToInvalidUrl()
|
||||
{
|
||||
$request = $this->createRequestWithBody(
|
||||
'https://example.com/object', Request::METHOD_POST, array( 'type' => 'Foo' )
|
||||
);
|
||||
$this->expectException( NotFoundHttpException::class );
|
||||
$this->controllerResolver->getController( $request );
|
||||
}
|
||||
|
||||
public function testItDisallowsNonGetPostMethods()
|
||||
{
|
||||
$request = $this->createRequestWithBody(
|
||||
'https://example.com/inbox', Request::METHOD_PUT, array( 'type' => 'Foo' )
|
||||
);
|
||||
$this->expectException( MethodNotAllowedHttpException::class );
|
||||
$this->controllerResolver->getController( $request );
|
||||
}
|
||||
}
|
||||
?>
|
14
test/Http/RouterTest.php
Normal file
14
test/Http/RouterTest.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
namespace ActivityPub\Test\Http;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class RouterTest extends TestCase
|
||||
{
|
||||
public function testRouter()
|
||||
{
|
||||
// TODO implement me
|
||||
$this->assertTrue( false );
|
||||
}
|
||||
}
|
||||
?>
|
Loading…
Reference in New Issue
Block a user