View source
<?php
namespace Drupal\Tests\big_pipe\Unit\Render;
use Drupal\big_pipe\Render\BigPipeResponse;
use Drupal\big_pipe\Render\BigPipeResponseAttachmentsProcessor;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Asset\AssetCollectionRendererInterface;
use Drupal\Core\Asset\AssetResolverInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Render\AttachmentsInterface;
use Drupal\Core\Render\AttachmentsResponseProcessorInterface;
use Drupal\Core\Render\HtmlResponse;
use Drupal\Core\Render\RendererInterface;
use Drupal\Tests\UnitTestCase;
use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy;
use Symfony\Component\HttpFoundation\RequestStack;
class BigPipeResponseAttachmentsProcessorTest extends UnitTestCase {
public function testNonHtmlResponse($response_class) {
$big_pipe_response_attachments_processor = $this
->createBigPipeResponseAttachmentsProcessor($this
->prophesize(AttachmentsResponseProcessorInterface::class));
$non_html_response = new $response_class();
$this
->expectException(\AssertionError::class);
$big_pipe_response_attachments_processor
->processAttachments($non_html_response);
}
public function nonHtmlResponseProvider() {
return [
'AjaxResponse, which implements AttachmentsInterface' => [
AjaxResponse::class,
],
'A dummy that implements AttachmentsInterface' => [
get_class($this
->prophesize(AttachmentsInterface::class)
->reveal()),
],
];
}
public function testHtmlResponse(array $attachments) {
$big_pipe_response = new BigPipeResponse(new HtmlResponse('original'));
$big_pipe_response
->setAttachments($attachments);
$html_response_attachments_processor = $this
->prophesize(AttachmentsResponseProcessorInterface::class);
$html_response_attachments_processor
->processAttachments(Argument::that(function ($response) {
return $response instanceof HtmlResponse && empty(array_intersect([
'big_pipe_placeholders',
'big_pipe_nojs_placeholders',
], array_keys($response
->getAttachments())));
}))
->will(function ($args) {
$response = $args[0];
$attachments = array_diff_key($response
->getAttachments(), [
'html_response_attachment_placeholders' => TRUE,
]);
$response
->setContent('processed');
$response
->setAttachments($attachments);
return $response;
})
->shouldBeCalled();
$big_pipe_response_attachments_processor = $this
->createBigPipeResponseAttachmentsProcessor($html_response_attachments_processor);
$processed_big_pipe_response = $big_pipe_response_attachments_processor
->processAttachments($big_pipe_response);
$this
->assertSame($attachments, $big_pipe_response
->getAttachments(), 'Attachments of original response object MUST NOT be changed.');
$this
->assertEquals('original', $big_pipe_response
->getContent(), 'Content of original response object MUST NOT be changed.');
$this
->assertEquals(array_diff_key($attachments, [
'html_response_attachment_placeholders' => TRUE,
]), $processed_big_pipe_response
->getAttachments(), 'Attachments of returned (processed) response object MUST be changed.');
$this
->assertEquals('processed', $processed_big_pipe_response
->getContent(), 'Content of returned (processed) response object MUST be changed.');
}
public function attachmentsProvider() {
$typical_cases = [
'no attachments' => [
[],
],
'libraries' => [
[
'library' => [
'core/drupal',
],
],
],
'libraries + drupalSettings' => [
[
'library' => [
'core/drupal',
],
'drupalSettings' => [
'foo' => 'bar',
],
],
],
];
$official_attachment_types = [
'html_head',
'feed',
'html_head_link',
'http_header',
'library',
'placeholders',
'drupalSettings',
'html_response_attachment_placeholders',
];
$official_attachments_with_random_values = [];
foreach ($official_attachment_types as $type) {
$official_attachments_with_random_values[$type] = $this
->randomMachineName();
}
$random_attachments = [
'random' . $this
->randomMachineName() => $this
->randomMachineName(),
];
$edge_cases = [
'all official attachment types, with random assigned values, even if technically not valid, to prove BigPipeResponseAttachmentsProcessor is a perfect decorator' => [
$official_attachments_with_random_values,
],
'random attachment type (unofficial), with random assigned value, to prove BigPipeResponseAttachmentsProcessor is a perfect decorator' => [
$random_attachments,
],
];
$big_pipe_placeholder_attachments = [
'big_pipe_placeholders' => [
$this
->randomMachineName(),
],
];
$big_pipe_nojs_placeholder_attachments = [
'big_pipe_nojs_placeholders' => [
$this
->randomMachineName(),
],
];
$big_pipe_cases = [
'only big_pipe_placeholders' => [
$big_pipe_placeholder_attachments,
],
'only big_pipe_nojs_placeholders' => [
$big_pipe_nojs_placeholder_attachments,
],
'big_pipe_placeholders + big_pipe_nojs_placeholders' => [
$big_pipe_placeholder_attachments + $big_pipe_nojs_placeholder_attachments,
],
];
$combined_cases = [
'all official attachment types + big_pipe_placeholders + big_pipe_nojs_placeholders' => [
$official_attachments_with_random_values + $big_pipe_placeholder_attachments + $big_pipe_nojs_placeholder_attachments,
],
'random attachment types + big_pipe_placeholders + big_pipe_nojs_placeholders' => [
$random_attachments + $big_pipe_placeholder_attachments + $big_pipe_nojs_placeholder_attachments,
],
];
return $typical_cases + $edge_cases + $big_pipe_cases + $combined_cases;
}
protected function createBigPipeResponseAttachmentsProcessor(ObjectProphecy $decorated_html_response_attachments_processor) {
return new BigPipeResponseAttachmentsProcessor($decorated_html_response_attachments_processor
->reveal(), $this
->prophesize(AssetResolverInterface::class)
->reveal(), $this
->prophesize(ConfigFactoryInterface::class)
->reveal(), $this
->prophesize(AssetCollectionRendererInterface::class)
->reveal(), $this
->prophesize(AssetCollectionRendererInterface::class)
->reveal(), $this
->prophesize(RequestStack::class)
->reveal(), $this
->prophesize(RendererInterface::class)
->reveal(), $this
->prophesize(ModuleHandlerInterface::class)
->reveal());
}
}