api-erstellen #1

Merged
TorstenHettstedt merged 52 commits from api-erstellen into master 2021-04-07 13:00:46 +02:00
3 changed files with 437 additions and 0 deletions
Showing only changes of commit e070db18b5 - Show all commits
@@ -0,0 +1,222 @@
<?php
namespace TorstenHettstedt\TimekeepingApi\Tests\Unit\Controller;
use Codeception\Test\Unit;
use Exception;
use PDO;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\StreamInterface;
use Slim\Exception\HttpBadRequestException;
use Slim\Exception\HttpInternalServerErrorException;
use Slim\Exception\HttpNotFoundException;
use Slim\Psr7\Request;
use Slim\Psr7\Response;
use TorstenHettstedt\TimekeepingApi\Controller\HttpConflictRequestException;
use TorstenHettstedt\TimekeepingApi\Controller\NotDatabasesException;
use TorstenHettstedt\TimekeepingApi\Controller\WorkingHoursController;
class WorkingHoursControllerTest extends Unit
{
const EXISTING_DATE = '2020-01-28';
const EXISTING_INTERVAL = '07:20:00';
const NEW_DATE = '2020-04-01';
const NEW_INTERVAL = '07:59:00';
protected ContainerInterface $container;
protected Request $request;
protected Response $response;
/**
* @throws Exception
*/
protected function _before(): void
{
parent::_before();
/** @noinspection SpellCheckingInspection */
$this->container = $this->makeEmpty(ContainerInterface::class, [
'has' => true,
'get' => new PDO('pgsql:host=psql.torsten-hettstedt.net;port=5432;dbname=testdb;user=bruce;password=mypass')
]);
$this->request = $this->makeEmpty(Request::class, [
'getParsedBody' => [
'workingDay' => self::EXISTING_DATE,
'workingTime' => self::EXISTING_INTERVAL,
]
]);
$this->response = $this->makeEmpty(Response::class, [
'getBody' => $this->makeEmpty(StreamInterface::class, [
'write' => function (mixed $data) {
$this->assertIsString($data);
$this->assertJson($data);
},
]),
'withHeader' => $this->makeEmpty(Response::class, [
'withStatus' => $this->makeEmpty(Response::class),
]),
]);
}
/**
* @throws NotDatabasesException
* @throws Exception
*/
public function testConstructWithNonDatabase(): void
{
$this->container = $this->makeEmpty(ContainerInterface::class, [
'has' => false
]);
$this->expectException(NotDatabasesException::class);
new WorkingHoursController($this->container);
}
/**
* @throws NotDatabasesException
* @throws Exception
*/
public function testBrowse(): void
{
$controller = new WorkingHoursController($this->container);
$response = $controller->browse($this->request, $this->response, []);
$this->assertInstanceOf(Response::class, $response);
}
/**
* @throws NotDatabasesException
* @throws HttpBadRequestException
* @throws HttpNotFoundException
*/
public function testUpdateExistRecord(): void
{
$controller = new WorkingHoursController($this->container);
$response = $controller->update($this->request, $this->response, [
'id' => self::EXISTING_DATE
]);
$this->assertInstanceOf(Response::class, $response);
}
/**
* @throws NotDatabasesException
* @throws HttpBadRequestException
* @throws HttpNotFoundException
*/
public function testUpdateNotExistRecord(): void
{
$controller = new WorkingHoursController($this->container);
$this->expectException(HttpNotFoundException::class);
$controller->update($this->request, $this->response, [
'id' => self::NEW_DATE
]);
}
/**
* @return string[][]
*/
public function invalidDataProvider(): array
{
return [
[
self::NEW_DATE,
'07:59'
],
[
'2020-13-33',
self::NEW_INTERVAL
],
];
}
/**
* @param string $date
* @param string $time
*
* @dataProvider invalidDataProvider
*
* @throws HttpBadRequestException
* @throws HttpConflictRequestException
* @throws HttpInternalServerErrorException
* @throws NotDatabasesException
* @throws Exception
*/
public function testCreatInvalidData(string $date, string $time): void
{
$this->request = $this->makeEmpty(Request::class, [
'getParsedBody' => [
'workingDay' => $date,
'workingTime' => $time,
]
]);
$controller = new WorkingHoursController($this->container);
$this->expectException(HttpBadRequestException::class);
$controller->creat($this->request, $this->response, []);
}
/**
* @throws HttpBadRequestException
* @throws NotDatabasesException
* @throws HttpInternalServerErrorException
* @throws HttpConflictRequestException
* @throws Exception
*/
public function testCreatNewRecord(): void
{
$this->request = $this->makeEmpty(Request::class, [
'getParsedBody' => [
'workingDay' => self::NEW_DATE,
'workingTime' => self::NEW_INTERVAL,
]
]);
$controller = new WorkingHoursController($this->container);
$response = $controller->creat($this->request, $this->response, []);
$this->assertInstanceOf(Response::class, $response);
}
/**
* @throws HttpBadRequestException
* @throws HttpConflictRequestException
* @throws HttpInternalServerErrorException
* @throws NotDatabasesException
* @throws Exception
*/
public function testCreatExistRecord(): void
{
$this->request = $this->makeEmpty(Request::class, [
'getParsedBody' => [
'workingDay' => self::EXISTING_DATE,
'workingTime' => self::EXISTING_INTERVAL,
]
]);
$controller = new WorkingHoursController($this->container);
$this->expectException(HttpConflictRequestException::class);
$controller->creat($this->request, $this->response, []);
}
/**
* @throws HttpInternalServerErrorException
* @throws HttpNotFoundException
* @throws NotDatabasesException
*/
public function testReadExistRecord(): void
{
$controller = new WorkingHoursController($this->container);
$response = $controller->read($this->request, $this->response, [
'id' => self::EXISTING_DATE
]);
$this->assertInstanceOf(Response::class, $response);
}
/**
* @throws HttpInternalServerErrorException
* @throws HttpNotFoundException
* @throws NotDatabasesException
*/
public function testReadNotExistRecord(): void
{
$controller = new WorkingHoursController($this->container);
$this->expectException(HttpNotFoundException::class);
$controller->read($this->request, $this->response, [
'id' => self::NEW_DATE
]);
}
}
@@ -0,0 +1,114 @@
<?php
namespace TorstenHettstedt\TimekeepingApi\Tests\Unit\Controller;
use Codeception\Test\Unit;
use Exception;
use PDO;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\StreamInterface;
use Slim\Psr7\Request;
use Slim\Psr7\Response;
use TorstenHettstedt\TimekeepingApi\Controller\NotDatabasesException;
use TorstenHettstedt\TimekeepingApi\Controller\WorkingHoursViewController;
class WorkingHoursViewControllerTest extends Unit
{
protected ContainerInterface $container;
protected Request $request;
protected Response $response;
/**
* @throws Exception
*/
protected function _before(): void
{
parent::_before();
/** @noinspection SpellCheckingInspection */
$this->container = $this->makeEmpty(ContainerInterface::class, [
'has' => true,
'get' => new PDO('pgsql:host=psql.torsten-hettstedt.net;port=5432;dbname=testdb;user=bruce;password=mypass')
]);
$this->request = $this->makeEmpty(Request::class, []);
$this->response = $this->makeEmpty(Response::class, [
'getBody' => $this->makeEmpty(StreamInterface::class, [
'write' => function (mixed $data) {
$this->assertIsString($data);
$this->assertJson($data);
},
]),
'withHeader' => $this->makeEmpty(Response::class, [
'withStatus' => $this->makeEmpty(Response::class),
]),
]);
}
TorstenHettstedt marked this conversation as resolved
Review

Zur Vereinfachung der Klasse soolte es den folgenden Test geben:

    /**
     * @throws NotDatabasesException
     * @throws Exception
     */
    public function testConstructWithNonDatabase(): void
    {
        $this->container = $this->makeEmpty(ContainerInterface::class, [
            'has' => false
        ]);
        $this->expectException(NotDatabasesException::class);
        new WorkingHoursViewController($this->container);
    }
Zur Vereinfachung der Klasse soolte es den folgenden Test geben: ``` /** * @throws NotDatabasesException * @throws Exception */ public function testConstructWithNonDatabase(): void { $this->container = $this->makeEmpty(ContainerInterface::class, [ 'has' => false ]); $this->expectException(NotDatabasesException::class); new WorkingHoursViewController($this->container); } ```
/**
* @throws Exception
*/
public function testBrowseMonthlyWithNonDatabase(): void
TorstenHettstedt marked this conversation as resolved
Review

Eine fehlende Datenbank sollte schon in der Erstellung des Objektes einen Fehler auslösen.

Eine fehlende Datenbank sollte schon in der Erstellung des Objektes einen Fehler auslösen.
{
$this->container = $this->makeEmpty(ContainerInterface::class, [
'has' => false
]);
$controller = new WorkingHoursViewController($this->container);
$this->expectException(NotDatabasesException::class);
$controller->browseMonthly($this->request, $this->response, []);
}
/**
* @throws Exception
*/
public function testBrowseMonthly(): void
{
$controller = new WorkingHoursViewController($this->container);
$response = $controller->browseMonthly($this->request, $this->response, []);
$this->assertInstanceOf(Response::class, $response);
}
/**
* @throws Exception
*/
public function testBrowseYearlyWithNonDatabase(): void
TorstenHettstedt marked this conversation as resolved
Review

Eine fehlende Datenbank sollte schon in der Erstellung des Objektes einen Fehler auslösen.

Eine fehlende Datenbank sollte schon in der Erstellung des Objektes einen Fehler auslösen.
{
$this->container = $this->makeEmpty(ContainerInterface::class, [
'has' => false
]);
$controller = new WorkingHoursViewController($this->container);
$this->expectException(NotDatabasesException::class);
$controller->browseYearly($this->request, $this->response, []);
}
/**
* @throws Exception
*/
public function testBrowseYearly(): void
{
$controller = new WorkingHoursViewController($this->container);
$response = $controller->browseYearly($this->request, $this->response, []);
$this->assertInstanceOf(Response::class, $response);
}
/**
* @throws Exception
*/
public function testBrowseWeeklyWithNonDatabase(): void
{
$this->container = $this->makeEmpty(ContainerInterface::class, [
'has' => false
]);
$controller = new WorkingHoursViewController($this->container);
$this->expectException(NotDatabasesException::class);
$controller->browseWeekly($this->request, $this->response, []);
}
/**
* @throws Exception
*/
public function testBrowseWeekly(): void
{
$controller = new WorkingHoursViewController($this->container);
$response = $controller->browseWeekly($this->request, $this->response, []);
$this->assertInstanceOf(Response::class, $response);
}
}
@@ -0,0 +1,101 @@
<?php
namespace TorstenHettstedt\TimekeepingApi\Tests\Unit\Middleware;
use Codeception\Stub\Expected;
use Codeception\Test\Unit;
use Exception;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Log\LoggerInterface;
use Slim\App;
use Slim\Exception\HttpException;
use TorstenHettstedt\TimekeepingApi\Middleware\ErrorHandler;
class ErrorHandlerTest extends Unit
{
protected App $app;
protected ServerRequestInterface $request;
protected Exception $exception;
protected LoggerInterface $logger;
/**
* @throws Exception
*/
protected function _before(): void
{
parent::_before();
$this->app = $this->makeEmpty(App::class, [
'getResponseFactory' => $this->makeEmpty(ResponseFactoryInterface::class, [
'createResponse' => $this->makeEmpty(ResponseInterface::class, [
'getBody' => $this->makeEmpty(StreamInterface::class, [
'write' => function (mixed $data) {
$this->assertIsString($data);
$this->assertJson($data);
},
]),
]),
]),
]);
$this->request = $this->makeEmpty(ServerRequestInterface::class);
}
/**
* @throws Exception
*/
public function testUseWithLogger(): void
{
$this->exception = $this->make(Exception::class, [
'message' => '',
'code' => 400,
'file' => '/path(to/file',
]);
$this->logger = $this->makeEmpty(LoggerInterface::class, [
'error' => Expected::once(),
]);
$middleWare = new ErrorHandler($this->app);
$middleWare($this->request, $this->exception, true, true, true, $this->logger);
}
/**
* @throws Exception
*/
public function testUseWithHttpException(): void
{
$this->exception = $this->make(HttpException::class, [
'message' => '',
'code' => 400,
'file' => '/path(to/file',
'getTitle' => Expected::once('The Title'),
]);
$this->logger = $this->makeEmpty(LoggerInterface::class, [
'error' => Expected::once(),
TorstenHettstedt marked this conversation as resolved
Review

Das ist hier nicht nötig.

Das ist hier nicht nötig.
]);
$middleWare = new ErrorHandler($this->app);
$middleWare($this->request, $this->exception, true, true, true, $this->logger);
}
/**
* @throws Exception
*/
public function testUseWithGeneralException(): void
{
$this->exception = $this->make(Exception::class, [
'message' => '',
'code' => 400,
'file' => '/path(to/file',
]);
$this->logger = $this->makeEmpty(LoggerInterface::class, [
'error' => Expected::once(),
TorstenHettstedt marked this conversation as resolved
Review

Das ist hier nicht nötig.

Das ist hier nicht nötig.
]);
$middleWare = new ErrorHandler($this->app);
$middleWare($this->request, $this->exception, true, true, true, $this->logger);
}
}