Skip to content

Commit

Permalink
Merge pull request #3 from RyanNerd/unit_testing
Browse files Browse the repository at this point in the history
Added some unit tests and fixed an issue with JsonBodyParser
  • Loading branch information
RyanNerd authored May 23, 2019
2 parents 07a95e0 + deaaf74 commit 7108428
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 2 deletions.
23 changes: 21 additions & 2 deletions app/Middleware/JsonBodyParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace Willow\Middleware;

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as RequestInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;

Expand All @@ -15,14 +15,33 @@
*/
class JsonBodyParser implements MiddlewareInterface
{
public function process(RequestInterface $request, RequestHandler $handler): Response
public function process(Request $request, RequestHandler $handler): Response
{
$contentType = $request->getHeaderLine('Content-Type');

// Is the content type JSON?
if (strstr($contentType, 'application/json')) {
// Try to get the JSON body as an associative array
$contents = json_decode(file_get_contents('php://input'), true);

// Is the JSON body valid?
if (json_last_error() === JSON_ERROR_NONE) {
$request = $request->withParsedBody($contents);
} else {
// Short circuit the request by returning a response with status of 400 (invalid request).
$responseBody = new ResponseBody();
$responseBody = $responseBody->setStatus(400)->setMessage('Invalid JSON');
return $responseBody();
}
} else {
$method = $request->getMethod();

// If the method is POST or PATCH the ONLY valid Content-Type is application/json
if ($method === 'POST' || $method === 'PATCH') {
// Short circuit the request by returning a response with status of 400 (invalid request).
$responseBody = new ResponseBody();
$responseBody = $responseBody->setStatus(400)->setMessage("Invalid Content-Type: $contentType");
return $responseBody();
}
}

Expand Down
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,8 @@
},
"scripts": {
"post-create-project-cmd":["Willow\\Robo\\Script::postCreateProjectCmd"]
},
"require-dev": {
"phpunit/phpunit": "^8"
}
}
70 changes: 70 additions & 0 deletions tests/JsonBodyParserTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);

use PHPUnit\Framework\TestCase;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Willow\Middleware\JsonBodyParser;

final class JsonBodyParserTest extends TestCase
{
public function testSanity()
{
$this->assertTrue(true);
}

/**
* JsonBodyParser should reject any Content-Type for POST other than application/json
*/
public function testInvalidContentTypePost()
{
$request = $this->createMock(Request::class);
$request->expects($this->once())->method('getHeaderLine')->willReturn('text/bogus');
$request->expects($this->once())->method('getMethod')->willReturn('POST');
$requestHandler = $this->createMock(RequestHandler::class);
$jsonBodyParser = new JsonBodyParser();
$response = $jsonBodyParser->process($request, $requestHandler);

$this->assertInstanceOf(Response::class, $response);

$bodyStream = $response->getBody();
$bodyStream->rewind();
$responseBody = $bodyStream->getContents();
$responseJSON = json_decode($responseBody, true);

$this->assertFalse($responseJSON['authenticated']);
$this->assertFalse($responseJSON['success']);
$this->assertEquals(400, $responseJSON['status']);
$this->assertNull($responseJSON['data']);
$this->assertEquals('Invalid Content-Type: text/bogus', $responseJSON['message']);
$this->assertIsNumeric($responseJSON['timestamp']);
}

/**
* JsonBodyParser should reject any Content-Type for PATCH other than application/json
*/
public function testInvalidContentTypePatch()
{
$request = $this->createMock(Request::class);
$request->expects($this->once())->method('getHeaderLine')->willReturn('text/bogus');
$request->expects($this->once())->method('getMethod')->willReturn('PATCH');
$requestHandler = $this->createMock(RequestHandler::class);
$jsonBodyParser = new JsonBodyParser();
$response = $jsonBodyParser->process($request, $requestHandler);

$this->assertInstanceOf(Response::class, $response);

$bodyStream = $response->getBody();
$bodyStream->rewind();
$responseBody = $bodyStream->getContents();
$responseJSON = json_decode($responseBody, true);

$this->assertFalse($responseJSON['authenticated']);
$this->assertFalse($responseJSON['success']);
$this->assertEquals(400, $responseJSON['status']);
$this->assertNull($responseJSON['data']);
$this->assertEquals('Invalid Content-Type: text/bogus', $responseJSON['message']);
$this->assertIsNumeric($responseJSON['timestamp']);
}
}
25 changes: 25 additions & 0 deletions tests/phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/|version|/phpunit.xsd"
backupGlobals="true"
backupStaticAttributes="false"
bootstrap="../vendor/autoload.php"
cacheResult="false"
cacheTokens="false"
colors="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
forceCoversAnnotation="false"
printerClass="PHPUnit\TextUI\ResultPrinter">
<testsuites>
<testsuite name="willow-app Tests">
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">../app</directory>
</whitelist>
</filter>
</phpunit>

0 comments on commit 7108428

Please sign in to comment.