<?php
namespace Szurubooru\Tests;
use Szurubooru\Router;
use Szurubooru\Tests\AbstractTestCase;
use Szurubooru\Tests\TestController;

final class PostDaoTest extends AbstractTestCase
{
	public function testParameterlessHandling()
	{
		$router = new Router;
		$testOk = false;
		$router->get('/test', function() use (&$testOk) { $testOk = true; });
		$router->handle('GET', '/test');
		$this->assertTrue($testOk);
	}

	public function testTrailingSlashes()
	{
		$router = new Router;
		$testOk = false;
		$router->get('/test', function() use (&$testOk) { $testOk = true; });
		$router->handle('GET', '/test/');
		$this->assertTrue($testOk);
	}

	public function testUnhandledMethod()
	{
		$router = new Router;
		$router->get('/test', function() { $this->fail('Route shouldn\'t be executed'); });
		$this->setExpectedException(\DomainException::class);
		$router->handle('POST', '/test');
	}

	public function testUnhandledQuery()
	{
		$router = new Router;
		$router->get('/test', function() { $this->fail('Route shouldn\'t be executed'); });
		$this->setExpectedException(\DomainException::class);
		$router->handle('GET', '/test2');
	}

	public function testTwoMethodsHandling()
	{
		$router = new Router;
		$testOk = false;
		$router->get('/test', function() { $this->fail('Route shouldn\'t be executed'); });
		$router->post('/test', function() use (&$testOk) { $testOk = true; });
		$router->handle('POST', '/test');
		$this->assertTrue($testOk);
	}

	public function testParameterHandling()
	{
		$router = new Router;
		$testOk = false;
		$router->get('/tests/:id', function($id) use (&$testOk) {
			$this->assertEquals($id, 'test_id');
			$testOk = true; });

		$router->handle('GET', '/tests/test_id');
		$this->assertTrue($testOk);
	}

	public function testTwoParameterHandling()
	{
		$router = new Router;
		$testOk = false;
		$router->get('/tests/:id/:page', function($id, $page) use (&$testOk) {
			$this->assertEquals($id, 'test_id');
			$this->assertEquals($page, 'test_page');
			$testOk = true; });

		$router->handle('GET', '/tests/test_id/test_page');
		$this->assertTrue($testOk);
	}

	public function testMissingParameterHandling()
	{
		$router = new Router;
		$testOk = false;
		$router->get('/tests/:id', function($id, $page) use (&$testOk) {
			$this->assertEquals($id, 'test_id');
			$this->assertNull($page);
			$testOk = true; });

		$router->handle('GET', '/tests/test_id');
		$this->assertTrue($testOk);
	}

	public function testMissingDefaultParameterHandling()
	{
		$router = new Router;
		$testOk = false;
		$router->get('/tests/:id', function($id, $page = 1) use (&$testOk) {
			$this->assertEquals($id, 'test_id');
			$this->assertEquals(1, $page);
			$testOk = true; });

		$router->handle('GET', '/tests/test_id');
		$this->assertTrue($testOk);
	}

	public function testOutputHandling()
	{
		$router = new Router;
		$router->get('/test', function() { return 'ok'; });
		$output = $router->handle('GET', '/test');
		$this->assertEquals('ok', $output);
	}

	public function testRoutingToClassMethods()
	{
		$router = new Router;
		$testController = new TestController();
		$router->get('/normal', [$testController, 'normalRoute']);
		$router->get('/static', [TestController::class, 'staticRoute']);
		$this->assertEquals('normal', $router->handle('GET', '/normal'));
		$this->assertEquals('static', $router->handle('GET', '/static'));
	}
}

class TestController
{
	public function normalRoute()
	{
		return 'normal';
	}

	public static function staticRoute()
	{
		return 'static';
	}
}