Core/tests/Traits/AppTestTrait.php

144 lines
4.1 KiB
PHP

<?php
declare(strict_types=1);
namespace Benzine\Tests\Traits;
use Benzine\App as BenzineApp;
use DI\Container;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UriInterface;
use Slim\App as SlimApp;
use Slim\Factory\ServerRequestCreatorFactory;
use Slim\Psr7\Factory\ServerRequestFactory;
/**
* Container Trait.
*/
trait AppTestTrait
{
protected Container $container;
protected BenzineApp $benzineApp;
protected SlimApp $slimApp;
/**
* Bootstrap app.
*
* @before
*
* @throws \UnexpectedValueException
*/
protected function setupContainer(): void
{
$this->benzineApp = require __DIR__ . '/../../../../../bootstrap.php';
$this->slimApp = $this->benzineApp->getApp();
$container = $this->slimApp->getContainer();
if ($container === null) {
throw new \UnexpectedValueException('Container must be initialized');
}
$this->container = $container;
$serverRequestCreator = ServerRequestCreatorFactory::create();
$request = $serverRequestCreator->createServerRequestFromGlobals();
$this->benzineApp->loadAllRoutes($request);
}
/**
* Add mock to container.
*
* @param string $class The class or interface
*
* @return MockObject The mock
*/
protected function mock(string $class): MockObject
{
if (!class_exists($class)) {
throw new \InvalidArgumentException(sprintf('Class not found: %s', $class));
}
$mock = $this->getMockBuilder($class)
->disableOriginalConstructor()
->getMock()
;
$this->container->set($class, $mock);
return $mock;
}
protected function getResponse(ServerRequestInterface $request): ResponseInterface
{
$response = $this->slimApp->handle($request);
$response->getBody()->rewind();
return $response;
}
/**
* Create a server request.
*
* @param string $method The HTTP method
* @param string|UriInterface $uri The URI
* @param array $serverParams The server parameters
*/
protected function createRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface
{
$this->setupContainer();
return (new ServerRequestFactory())->createServerRequest($method, $uri, $serverParams);
}
/**
* Create a JSON request.
*
* @param string $method The HTTP method
* @param string|UriInterface $uri The URI
* @param null|array $data The json data
*/
protected function createJsonRequest(string $method, $uri, ?array $data = null): ServerRequestInterface
{
$request = $this->createRequest($method, $uri);
if ($data !== null) {
$request = $request->withParsedBody($data);
}
return $request->withHeader('Content-Type', 'application/json');
}
/**
* Create a form request.
*
* @param string $method The HTTP method
* @param string|UriInterface $uri The URI
* @param null|array $data The form data
*/
protected function createFormRequest(string $method, $uri, ?array $data = null): ServerRequestInterface
{
$request = $this->createRequest($method, $uri);
if ($data !== null) {
$request = $request->withParsedBody($data);
}
return $request->withHeader('Content-Type', 'application/x-www-form-urlencoded');
}
/**
* Verify that the specified array is an exact match for the returned JSON.
*
* @param ResponseInterface $response The response
* @param array $expected The expected array
*/
protected function assertJsonData(ResponseInterface $response, array $expected): void
{
$actual = (string) $response->getBody();
$this->assertJson($actual);
$this->assertSame($expected, (array) json_decode($actual, true));
}
}