Skip to content

Improve tests, replace psr7 implementation #152

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Bridges/HttpKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UploadedFileInterface;
use RingCentral\Psr7;
use GuzzleHttp\Psr7;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that's not really needed here but it reduces the number of dependencies?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a change to a more complete PSR7 implementation and to a better maintained library, it doesn't really change the number of dependencies itself.

Also, the Psr7 Response object is used here. Are you refering to something else?

use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\File\UploadedFile as SymfonyFile;
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
Expand Down
10 changes: 6 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
"license": "MIT",
"require": {
"php-pm/php-pm": "^1.0.5",
"symfony/http-foundation": "^2.6|^3.0|^4",
"symfony/http-kernel": "^2.6|^3.0|^4",
"ringcentral/psr7": "^1.2"
"symfony/http-foundation": "^3.4|^4",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dropped 2.X already

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think- can we release this in a point release? Effectively we're dropping support for Symfony before 3.4?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The proposed 'kernel.reset' interface for Symfony is only in 3.4+. Also, SF 2.x is EOL already, I'd say it's time to move on.

"symfony/http-kernel": "^3.4|^4",
"guzzlehttp/psr7": "^1.5"
},
"require-dev": {
"phpunit/phpunit": "^5.7"
"phpunit/phpunit": "^5.7",
"symfony/framework-bundle": "^3.4|^4",
"doctrine/annotations": "^1.6"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to require the annotations here or aren't they implicit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nopes, they aren't implicit, Symfony relies on them for routing annotation but you need to import the library yourself

},
"autoload": {
"psr-4": {
Expand Down
13 changes: 13 additions & 0 deletions tests/Fixtures/ProcessSlaveDouble.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace PHPPM\Tests\Fixtures;

class ProcessSlaveDouble
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used to have support for the register_file function without having a real Slave

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will be useful when creating a test that checks if a symfony container resource is actually being added to the list of watched files

{
private $watchedFiles = [];

public function registerFile($file)
{
$this->watchedFiles[] = $file;
}
}
18 changes: 18 additions & 0 deletions tests/Fixtures/Symfony/Controller/GetController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace PHPPM\Tests\Fixtures\Symfony\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class GetController extends Controller
{
/**
* @Route("/get")
*/
public function __invoke()
{
return new Response('Success', 200);
}
}
24 changes: 24 additions & 0 deletions tests/Fixtures/Symfony/Controller/PostJsonController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace PHPPM\Tests\Fixtures\Symfony\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class PostJsonController extends Controller
{
/**
* @Route("/json", methods={"POST"})
*/
public function __invoke(Request $request)
{
$body = json_decode($request->getContent(), true);
if ($request->getContent() == null || !$body) {
throw new \Exception('Invalid JSON body');
}

return new Response('Received JSON: '.$request->getContent(), 201);
}
}
20 changes: 20 additions & 0 deletions tests/Fixtures/Symfony/Controller/StreamedController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace PHPPM\Tests\Fixtures\Symfony\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Routing\Annotation\Route;

class StreamedController extends Controller
{
/**
* @Route("/streamed")
*/
public function __invoke()
{
return new StreamedResponse(function () {
echo 'streamed data';
}, 200);
}
}
26 changes: 26 additions & 0 deletions tests/Fixtures/Symfony/Controller/UploadController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace PHPPM\Tests\Fixtures\Symfony\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class UploadController extends Controller
{
/**
* @Route("/upload", methods={"POST"})
*/
public function __invoke(Request $request)
{
$mappedFileNames = array_map(function ($f) {
if (!isset($f)) {
return 'NULL';
}
return $f->getClientOriginalName();
}, $request->files->all());

return new Response('Uploaded files: '.implode(',', $mappedFileNames), 201);
}
}
50 changes: 50 additions & 0 deletions tests/Fixtures/Symfony/Kernel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace PHPPM\Tests\Fixtures\Symfony;

use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Routing\RouteCollectionBuilder;

class Kernel extends \Symfony\Component\HttpKernel\Kernel
{
use MicroKernelTrait;

const CONFIG_EXTS = '.{php,xml,yaml,yml}';

public function registerBundles()
{
$contents = require $this->getProjectDir() . '/config/bundles.php';
foreach ($contents as $class => $envs) {
if (isset($envs['all']) || isset($envs[$this->environment])) {
yield new $class();
}
}
}

protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
{
$container->addResource(new FileResource($this->getProjectDir() . '/config/bundles.php'));
// Feel free to remove the "container.autowiring.strict_mode" parameter
// if you are using symfony/dependency-injection 4.0+ as it's the default behavior
$container->setParameter('container.autowiring.strict_mode', true);
$container->setParameter('container.dumper.inline_class_loader', true);
$confDir = $this->getProjectDir() . '/config';

$loader->load($confDir . '/{services}' . self::CONFIG_EXTS, 'glob');
}

protected function configureRoutes(RouteCollectionBuilder $routes)
{
$confDir = $this->getProjectDir() . '/config';

$routes->import($confDir . '/{routes}' . self::CONFIG_EXTS, '/', 'glob');
}

public function getProjectDir()
{
return __DIR__;
}
}
5 changes: 5 additions & 0 deletions tests/Fixtures/Symfony/config/bundles.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

return [
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
];
3 changes: 3 additions & 0 deletions tests/Fixtures/Symfony/config/routes.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
controllers:
resource: '../Controller/'
type: annotation
3 changes: 3 additions & 0 deletions tests/Fixtures/Symfony/config/services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
services:
framework:
secret: foobar
79 changes: 36 additions & 43 deletions tests/SymfonyBootstrapTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,61 @@

namespace PHPPM\Tests;

use PHPPM\ProcessSlave;
use PHPPM\Tests\Fixtures\ProcessSlaveDouble;
use PHPUnit\Framework\TestCase;
use PHPPM\Bridges\HttpKernel;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UploadedFileInterface;
use GuzzleHttp\Psr7\ServerRequest;
use GuzzleHttp\Psr7\UploadedFile;
use Symfony\Component\Filesystem\Filesystem;

class SymfonyBootstrapTest extends TestCase
{
public function setUp()
{
ProcessSlave::$slave = new ProcessSlaveDouble();
}

public static function tearDownAfterClass()
{
$fs = new Filesystem();
$fs->remove(__DIR__.'/Fixtures/Symfony/var');
}

/**
* @runInSeparateProcess
*/
public function testGetRequest()
{
putenv('APP_KERNEL_NAMESPACE=PHPPM\\Tests\\SymfonyMocks\\');
putenv('APP_KERNEL_NAMESPACE=PHPPM\\Tests\\Fixtures\\Symfony\\');
$bridge = new HttpKernel();
$bridge->bootstrap('Symfony', 'test', true);

$request = $this->getMockBuilder(ServerRequestInterface::class)->getMock();
$request->method('getHeader')->with('Cookie')->willReturn([]);
$request->method('getQueryParams')->willReturn([]);
$request->method('getUploadedFiles')->willReturn([]);
$request->method('getMethod')->willReturn('GET');
$request = new ServerRequest('GET', '/get');
$_SERVER['REQUEST_URI'] = (string) $request->getUri();

$response = $bridge->handle($request);
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals('Success', (string)$response->getBody());
$this->assertEquals('Success', (string) $response->getBody());
}

/**
* @runInSeparateProcess
*/
public function testFileUpload()
{
putenv('APP_KERNEL_NAMESPACE=PHPPM\\Tests\\SymfonyMocks\\');
putenv('APP_KERNEL_NAMESPACE=PHPPM\\Tests\\Fixtures\\Symfony\\');
$bridge = new HttpKernel();
$bridge->bootstrap('Symfony', 'test', true);

$fileOK = $this->getMockBuilder(UploadedFileInterface::class)->getMock();
$fileOK->method('getClientFilename')->willReturn('testOK.pdf');
$fileOK->method('getClientMediaType')->willReturn('pdf');
$fileOK->method('getSize')->willReturn(1000);
$fileOK->method('getError')->willReturn(UPLOAD_ERR_OK);

$fileErr = $this->getMockBuilder(UploadedFileInterface::class)->getMock();
$fileErr->method('getClientFilename')->willReturn('testErr.pdf');
$fileErr->method('getClientMediaType')->willReturn('pdf');
$fileErr->method('getSize')->willReturn(0);
$fileErr->method('getError')->willReturn(UPLOAD_ERR_NO_FILE);

$request = $this->getMockBuilder(ServerRequestInterface::class)->getMock();
$request->method('getHeader')->with('Cookie')->willReturn([]);
$request->method('getQueryParams')->willReturn([]);
$request->method('getUploadedFiles')->willReturn([$fileOK, $fileErr]);
$request->method('getMethod')->willReturn('POST');
$request = new ServerRequest('POST', '/upload');
$dummyStream = fopen('data:text/plain,dummy', 'r');
$uploadedFiles = [
new UploadedFile($dummyStream, 1000, UPLOAD_ERR_OK, 'testOK.pdf', 'pdf'),
new UploadedFile($dummyStream, 0, UPLOAD_ERR_NO_FILE, 'testErr.pdf', 'pdf'),
];
$request = $request->withUploadedFiles($uploadedFiles);
$_SERVER['REQUEST_URI'] = (string) $request->getUri();

$response = $bridge->handle($request);
$this->assertEquals(201, $response->getStatusCode());
Expand All @@ -67,17 +68,14 @@ public function testFileUpload()
*/
public function testPostJSON()
{
putenv('APP_KERNEL_NAMESPACE=PHPPM\\Tests\\SymfonyMocks\\');
putenv('APP_KERNEL_NAMESPACE=PHPPM\\Tests\\Fixtures\\Symfony\\');
$bridge = new HttpKernel();
$bridge->bootstrap('Symfony', 'test', true);

$_SERVER["CONTENT_TYPE"] = 'application/json';
$request = $this->getMockBuilder(ServerRequestInterface::class)->getMock();
$request->method('getHeader')->with('Cookie')->willReturn([]);
$request->method('getQueryParams')->willReturn([]);
$request->method('getUploadedFiles')->willReturn([]);
$request->method('getBody')->willReturn('{"some_json_array":[{"map1":"value1"},{"map2":"value2"}]}');
$request->method('getMethod')->willReturn('POST');
$request = new ServerRequest('POST', '/json', [
'CONTENT_TYPE' => 'application/json',
], '{"some_json_array":[{"map1":"value1"},{"map2":"value2"}]}');
$_SERVER['REQUEST_URI'] = (string) $request->getUri();

$response = $bridge->handle($request);
$this->assertEquals(201, $response->getStatusCode());
Expand All @@ -89,17 +87,12 @@ public function testPostJSON()
*/
public function testStreamedResponse()
{
putenv('APP_KERNEL_NAMESPACE=PHPPM\\Tests\\SymfonyMocks\\');
putenv('APP_KERNEL_NAMESPACE=PHPPM\\Tests\\Fixtures\\Symfony\\');
$bridge = new HttpKernel();
$bridge->bootstrap('Symfony', 'test', true);

$request = $this->getMockBuilder(ServerRequestInterface::class)->getMock();
$request->method('getHeader')->with('Cookie')->willReturn([]);
$request->method('getQueryParams')->willReturn([]);
$request->method('getUploadedFiles')->willReturn([]);
$request->method('getMethod')->willReturn('GET');

$_SERVER['REQUEST_URI'] = '/streamed';
$request = new ServerRequest('GET', '/streamed');
$_SERVER['REQUEST_URI'] = (string) $request->getUri();

$response = $bridge->handle($request);
$this->assertEquals(200, $response->getStatusCode());
Expand Down
13 changes: 0 additions & 13 deletions tests/SymfonyMocks/Container.php

This file was deleted.

Loading