Skip to content
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

Add attributes to the unformatted response #10

Merged
merged 3 commits into from
Apr 22, 2018
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 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