Skip to content

Commit

Permalink
Merge pull request #10 from lcobucci/add-attributes
Browse files Browse the repository at this point in the history
Add attributes to the unformatted response
  • Loading branch information
lcobucci authored Apr 22, 2018
2 parents 5297cc3 + 634f10d commit af87ff9
Show file tree
Hide file tree
Showing 10 changed files with 231 additions and 30 deletions.
2 changes: 1 addition & 1 deletion src/ContentTypeMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ private function formatResponse(UnformattedResponse $response, ?Formatter $forma
return $response->withStatus(StatusCodeInterface::STATUS_NOT_ACCEPTABLE);
}

$body->write($formatter->format($response->getUnformattedContent()));
$body->write($formatter->format($response->getUnformattedContent(), $response->getAttributes()));
$body->rewind();

return $response;
Expand Down
5 changes: 3 additions & 2 deletions src/Formatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
interface Formatter
{
/**
* @param mixed $content
* @param mixed $content
* @param mixed[] $attributes
*
* @throw ContentCouldNotBeFormatted
*/
public function format($content): string;
public function format($content, array $attributes = []): string;
}
2 changes: 1 addition & 1 deletion src/Formatter/JmsSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function __construct(SerializerInterface $serializer, string $format)
/**
* {@inheritdoc}
*/
public function format($content): string
public function format($content, array $attributes = []): string
{
try {
return $this->serializer->serialize($content, $this->format);
Expand Down
2 changes: 1 addition & 1 deletion src/Formatter/Json.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function __construct(int $flags = self::DEFAULT_FLAGS)
/**
* {@inheritdoc}
*/
public function format($content): string
public function format($content, array $attributes = []): string
{
try {
$encoded = json_encode($content, $this->flags);
Expand Down
2 changes: 1 addition & 1 deletion src/Formatter/StringCast.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ final class StringCast implements Formatter
/**
* {@inheritdoc}
*/
public function format($content): string
public function format($content, array $attributes = []): string
{
if (is_object($content) && ! method_exists($content, '__toString')) {
throw new ContentCouldNotBeFormatted('Given data could not be cast to string');
Expand Down
58 changes: 49 additions & 9 deletions src/UnformattedResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,22 @@ final class UnformattedResponse implements ResponseInterface
private $unformattedContent;

/**
* @param mixed $unformattedContent
* @var mixed[]
*/
public function __construct(ResponseInterface $decoratedResponse, $unformattedContent)
{
private $attributes;

/**
* @param mixed $unformattedContent
* @param mixed[] $attributes
*/
public function __construct(
ResponseInterface $decoratedResponse,
$unformattedContent,
array $attributes = []
) {
$this->decoratedResponse = $decoratedResponse;
$this->unformattedContent = $unformattedContent;
$this->attributes = $attributes;
}

/**
Expand All @@ -50,7 +60,8 @@ public function withProtocolVersion($version)
{
return new self(
$this->decoratedResponse->withProtocolVersion($version),
$this->unformattedContent
$this->unformattedContent,
$this->attributes
);
}

Expand Down Expand Up @@ -93,7 +104,8 @@ public function withHeader($name, $value)
{
return new self(
$this->decoratedResponse->withHeader($name, $value),
$this->unformattedContent
$this->unformattedContent,
$this->attributes
);
}

Expand All @@ -104,7 +116,8 @@ public function withAddedHeader($name, $value)
{
return new self(
$this->decoratedResponse->withAddedHeader($name, $value),
$this->unformattedContent
$this->unformattedContent,
$this->attributes
);
}

Expand All @@ -115,7 +128,8 @@ public function withoutHeader($name)
{
return new self(
$this->decoratedResponse->withoutHeader($name),
$this->unformattedContent
$this->unformattedContent,
$this->attributes
);
}

Expand All @@ -134,7 +148,8 @@ public function withBody(StreamInterface $body)
{
return new self(
$this->decoratedResponse->withBody($body),
$this->unformattedContent
$this->unformattedContent,
$this->attributes
);
}

Expand All @@ -153,7 +168,8 @@ public function withStatus($code, $reasonPhrase = '')
{
return new self(
$this->decoratedResponse->withStatus($code, $reasonPhrase),
$this->unformattedContent
$this->unformattedContent,
$this->attributes
);
}

Expand All @@ -164,4 +180,28 @@ public function getReasonPhrase()
{
return $this->decoratedResponse->getReasonPhrase();
}

/**
* Returns an instance with the specified attribute
*
* @param mixed $value
*/
public function withAttribute(string $name, $value): self
{
return new self(
$this->decoratedResponse,
$this->unformattedContent,
[$name => $value] + $this->attributes
);
}

/**
* Retrieve the configured attributes
*
* @return mixed[]
*/
public function getAttributes(): array
{
return $this->attributes;
}
}
70 changes: 57 additions & 13 deletions tests/ContentTypeMiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Fig\Http\Message\StatusCodeInterface;
use Lcobucci\ContentNegotiation\ContentTypeMiddleware;
use Lcobucci\ContentNegotiation\Formatter;
use Lcobucci\ContentNegotiation\Tests\Formatter\NaiveTemplateEngine;
use Lcobucci\ContentNegotiation\UnformattedResponse;
use PHPUnit\Framework\Error\Warning;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -60,9 +61,7 @@ public function processShouldReturnAResponseWithErrorWhenFormatterWasNotFound():

$response = $middleware->process(
(new ServerRequest())->withAddedHeader('Accept', 'text/plain'),
$this->createRequestHandler(
new UnformattedResponse(new Response(), new PersonDto(1, 'Testing'))
)
$this->createRequestHandler($this->createResponse())
);

self::assertInstanceOf(UnformattedResponse::class, $response);
Expand All @@ -88,9 +87,7 @@ public function processShouldReturnAResponseWithFormattedContent(): void

$response = $middleware->process(
new ServerRequest(),
$this->createRequestHandler(
new UnformattedResponse(new Response(), new PersonDto(1, 'Testing'))
)
$this->createRequestHandler($this->createResponse())
);

self::assertInstanceOf(UnformattedResponse::class, $response);
Expand All @@ -99,6 +96,37 @@ public function processShouldReturnAResponseWithFormattedContent(): void
self::assertJsonStringEqualsJsonString('{"id":1,"name":"Testing"}', (string) $response->getBody());
}

/**
* @test
*
* @covers ::__construct()
* @covers ::fromRecommendedSettings()
* @covers ::process()
* @covers ::extractContentType()
* @covers ::formatResponse()
*
* @uses \Lcobucci\ContentNegotiation\UnformattedResponse
* @uses \Lcobucci\ContentNegotiation\Formatter\Json
*/
public function processShouldPassAttributesToTheFormatterProperly(): void
{
$middleware = $this->createMiddleware();

$response = $middleware->process(
(new ServerRequest())->withAddedHeader('Accept', 'text/html'),
$this->createRequestHandler($this->createResponse(['template' => 'person']))
);

self::assertInstanceOf(UnformattedResponse::class, $response);
self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode());
self::assertSame('text/html; charset=UTF-8', $response->getHeaderLine('Content-Type'));

$body = (string) $response->getBody();

self::assertContains('<dd>1</dd>', $body);
self::assertContains('<dd>Testing</dd>', $body);
}

/**
* @test
*
Expand All @@ -117,9 +145,7 @@ public function processShouldReturnAResponseWithFormattedContentEvenWithoutForci

$response = $middleware->process(
new ServerRequest(),
$this->createRequestHandler(
new UnformattedResponse(new Response(), new PersonDto(1, 'Testing'))
)
$this->createRequestHandler($this->createResponse())
);

self::assertInstanceOf(UnformattedResponse::class, $response);
Expand Down Expand Up @@ -179,9 +205,19 @@ function () {

$middleware->process(
new ServerRequest(),
$this->createRequestHandler(
new UnformattedResponse(new Response(), new PersonDto(1, 'Testing'))
)
$this->createRequestHandler($this->createResponse())
);
}

/**
* @param mixed[] $attributes
*/
private function createResponse(array $attributes = []): UnformattedResponse
{
return new UnformattedResponse(
new Response(),
new PersonDto(1, 'Testing'),
$attributes
);
}

Expand Down Expand Up @@ -223,8 +259,16 @@ private function createMiddleware(bool $forceCharset = true, ?callable $streamFa
'mime-type' => ['text/plain'],
'charset' => $forceCharset,
],
'html' => [
'extension' => ['html', 'htm'],
'mime-type' => ['text/html', 'application/xhtml+xml'],
'charset' => $forceCharset,
],
],
[
'application/json' => new Formatter\Json(),
'text/html' => new NaiveTemplateEngine(),
],
['application/json' => new Formatter\Json()],
$streamFactory
);
}
Expand Down
57 changes: 57 additions & 0 deletions tests/Formatter/NaiveTemplateEngine.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);

namespace Lcobucci\ContentNegotiation\Tests\Formatter;

use Lcobucci\ContentNegotiation\Formatter;
use SplFileObject;
use function array_keys;
use function array_map;
use function assert;
use function is_string;
use function str_replace;
use function trim;

final class NaiveTemplateEngine implements Formatter
{
private const BASE_DIR = __DIR__ . '/templates/naive/';
private const EXTENSION = 'html';

/**
* {@inheritdoc}
*/
public function format($content, array $attributes = []): string
{
$template = $this->getTemplateContent($attributes);

return $this->render($template, (array) $content);
}

/**
* @param mixed[] $attributes
*/
private function getTemplateContent(array $attributes): string
{
$template = $attributes['template'] ?? '';
assert(is_string($template));

$file = new SplFileObject(self::BASE_DIR . $template . '.' . self::EXTENSION);

return $file->fread($file->getSize());
}

/**
* @param mixed[] $data
*/
private function render(string $template, array $data): string
{
$variables = array_map(
function (string $attribute): string {
return '{' . $attribute . '}';
},
array_keys($data)
);

return trim(str_replace($variables, $data, $template));
}
}
8 changes: 8 additions & 0 deletions tests/Formatter/templates/naive/person.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<section>
<dl>
<dt>Identifier</dt>
<dd>{id}</dd>
<dt>Name</dt>
<dd>{name}</dd>
</dl>
</section>
Loading

0 comments on commit af87ff9

Please sign in to comment.