<?php
namespace Szurubooru\Tests;
use Szurubooru\Injector;
use Szurubooru\RouteRepository;
use Szurubooru\Router;
use Szurubooru\Routes\AbstractRoute;
use Szurubooru\Tests\AbstractDatabaseTestCase;

final class RouteRepositoryTest extends AbstractDatabaseTestCase
{
    public function testFactory()
    {
        $routeRepository = Injector::get(RouteRepository::class);
        $this->assertNotEmpty($routeRepository->getRoutes());
    }

    public function testRouteMethods()
    {
        $routeRepository = Injector::get(RouteRepository::class);
        foreach ($routeRepository->getRoutes() as $route)
        {
            foreach ($route->getMethods() as $method)
            {
                $this->assertContains($method, ['GET', 'POST', 'PUT', 'DELETE']);
            }
        }
    }

    public function testRouteUrls()
    {
        $routeRepository = Injector::get(RouteRepository::class);
        foreach ($routeRepository->getRoutes() as $route)
        {
            $this->assertEquals(0, strpos($route->getUrl(), '/api/'));
        }
    }

    public function testRouteInjection()
    {
        $routerMock = $this->mock(Router::class);
        $routeMock = $this->mock(AbstractRoute::class);
        $routeMock->expects($this->once())->method('getMethods')->willReturn(['POST', 'GET']);
        $routeMock->expects($this->atLeast(1))->method('getUrl')->willReturn('/test');
        $routerMock->expects($this->once())->method('post')->with('/test', $this->anything());
        $routerMock->expects($this->once())->method('get')->with('/test', $this->anything());
        $routeRepository = new RouteRepository([$routeMock]);
        $routeRepository->injectRoutes($routerMock);
    }

    public function testRouteCallbackInjection()
    {
        $router = new Router();
        $routeMock = $this->mock(AbstractRoute::class);
        $routeMock->expects($this->once())->method('getMethods')->willReturn(['POST', 'GET']);
        $routeMock->expects($this->atLeast(1))->method('getUrl')->willReturn('/test');
        $routeMock->expects($this->atLeast(1))->method('work');
        $routeRepository = new RouteRepository([$routeMock]);
        $routeRepository->injectRoutes($router);
        $router->handle('GET', '/test');
    }
}