You've already forked wp-bootstrap
174 lines
6.4 KiB
PHP
174 lines
6.4 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
namespace WPBootstrap\Tests\Unit\Block;
|
||
|
|
|
||
|
|
use PHPUnit\Framework\TestCase;
|
||
|
|
use Brain\Monkey;
|
||
|
|
use Brain\Monkey\Functions;
|
||
|
|
use WPBootstrap\Block\WidgetRenderer;
|
||
|
|
|
||
|
|
class WidgetRendererTest extends TestCase
|
||
|
|
{
|
||
|
|
private WidgetRenderer $renderer;
|
||
|
|
|
||
|
|
protected function setUp(): void
|
||
|
|
{
|
||
|
|
parent::setUp();
|
||
|
|
Monkey\setUp();
|
||
|
|
|
||
|
|
// Skip constructor filter registration.
|
||
|
|
Functions\when('is_admin')->justReturn(true);
|
||
|
|
Functions\when('wp_doing_ajax')->justReturn(false);
|
||
|
|
|
||
|
|
$this->renderer = new WidgetRenderer();
|
||
|
|
}
|
||
|
|
|
||
|
|
protected function tearDown(): void
|
||
|
|
{
|
||
|
|
Monkey\tearDown();
|
||
|
|
parent::tearDown();
|
||
|
|
}
|
||
|
|
|
||
|
|
// ── wrapWidgetInCard ────────────────────────────────────────
|
||
|
|
|
||
|
|
public function testWrapWidgetInCardSetsCardStructure(): void
|
||
|
|
{
|
||
|
|
Functions\when('esc_attr')->returnArg();
|
||
|
|
|
||
|
|
$params = $this->makeParams('block-2', 'widget mb-4 widget_block');
|
||
|
|
$result = $this->renderer->wrapWidgetInCard($params);
|
||
|
|
|
||
|
|
$this->assertStringContainsString('card', $result[0]['before_widget']);
|
||
|
|
$this->assertStringContainsString('card-body', $result[0]['before_widget']);
|
||
|
|
$this->assertSame('</div></div>', $result[0]['after_widget']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testWrapWidgetInCardSetsCardTitle(): void
|
||
|
|
{
|
||
|
|
Functions\when('esc_attr')->returnArg();
|
||
|
|
|
||
|
|
$params = $this->makeParams('block-3', 'widget mb-4 widget_block');
|
||
|
|
$result = $this->renderer->wrapWidgetInCard($params);
|
||
|
|
|
||
|
|
$this->assertStringContainsString('<h4', $result[0]['before_title']);
|
||
|
|
$this->assertStringContainsString('card-title', $result[0]['before_title']);
|
||
|
|
$this->assertSame('</h4>', $result[0]['after_title']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testWrapWidgetInCardPreservesWidgetId(): void
|
||
|
|
{
|
||
|
|
Functions\when('esc_attr')->returnArg();
|
||
|
|
|
||
|
|
$params = $this->makeParams('search-1', 'widget mb-4 widget_search');
|
||
|
|
$result = $this->renderer->wrapWidgetInCard($params);
|
||
|
|
|
||
|
|
$this->assertStringContainsString('id="search-1"', $result[0]['before_widget']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testWrapWidgetInCardPreservesWidgetTypeClasses(): void
|
||
|
|
{
|
||
|
|
Functions\when('esc_attr')->returnArg();
|
||
|
|
|
||
|
|
$params = $this->makeParams('block-5', 'widget mb-4 widget_block wp-block-heading');
|
||
|
|
$result = $this->renderer->wrapWidgetInCard($params);
|
||
|
|
|
||
|
|
// widget_block and wp-block-heading are kept; widget and mb-4 are removed.
|
||
|
|
$this->assertStringContainsString('widget_block', $result[0]['before_widget']);
|
||
|
|
$this->assertStringContainsString('wp-block-heading', $result[0]['before_widget']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testWrapWidgetInCardFiltersGenericClasses(): void
|
||
|
|
{
|
||
|
|
Functions\when('esc_attr')->returnArg();
|
||
|
|
|
||
|
|
$params = $this->makeParams('block-2', 'widget mb-4 widget_block');
|
||
|
|
$result = $this->renderer->wrapWidgetInCard($params);
|
||
|
|
|
||
|
|
// The card wrapper adds its own "widget" class, but the extracted
|
||
|
|
// classes should not include the generic "widget" or "mb-4".
|
||
|
|
// Count occurrences: "card mb-3 widget " + "widget_block" should have exactly one "widget".
|
||
|
|
preg_match_all('/\bwidget\b/', $result[0]['before_widget'], $matches);
|
||
|
|
$this->assertCount(1, $matches[0], 'Generic "widget" class should appear once (from card wrapper), not duplicated');
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testWrapWidgetInCardWithNoExistingClasses(): void
|
||
|
|
{
|
||
|
|
Functions\when('esc_attr')->returnArg();
|
||
|
|
|
||
|
|
$params = [
|
||
|
|
[
|
||
|
|
'widget_id' => 'text-1',
|
||
|
|
'before_widget' => '<div id="text-1">',
|
||
|
|
'after_widget' => '</div>',
|
||
|
|
'before_title' => '<h3>',
|
||
|
|
'after_title' => '</h3>',
|
||
|
|
],
|
||
|
|
];
|
||
|
|
|
||
|
|
$result = $this->renderer->wrapWidgetInCard($params);
|
||
|
|
|
||
|
|
$this->assertStringContainsString('card', $result[0]['before_widget']);
|
||
|
|
$this->assertStringContainsString('id="text-1"', $result[0]['before_widget']);
|
||
|
|
}
|
||
|
|
|
||
|
|
// ── processBlockWidgetContent ───────────────────────────────
|
||
|
|
|
||
|
|
public function testProcessBlockWidgetContentReplacesH2WithH4(): void
|
||
|
|
{
|
||
|
|
$content = '<h2 class="wp-block-heading">Categories</h2><ul><li>Cat A</li></ul>';
|
||
|
|
$widget = new \WP_Widget();
|
||
|
|
|
||
|
|
$result = $this->renderer->processBlockWidgetContent($content, [], $widget);
|
||
|
|
|
||
|
|
$this->assertStringContainsString('<h4 class="wp-block-heading">', $result);
|
||
|
|
$this->assertStringContainsString('</h4>', $result);
|
||
|
|
$this->assertStringNotContainsString('<h2', $result);
|
||
|
|
$this->assertStringNotContainsString('</h2>', $result);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testProcessBlockWidgetContentPreservesOtherH2(): void
|
||
|
|
{
|
||
|
|
$content = '<h2 class="custom-heading">Keep me</h2>';
|
||
|
|
$widget = new \WP_Widget();
|
||
|
|
|
||
|
|
$result = $this->renderer->processBlockWidgetContent($content, [], $widget);
|
||
|
|
|
||
|
|
// h2 without wp-block-heading class should remain.
|
||
|
|
$this->assertStringContainsString('<h2 class="custom-heading">', $result);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testProcessBlockWidgetContentEmptyReturnsEmpty(): void
|
||
|
|
{
|
||
|
|
$widget = new \WP_Widget();
|
||
|
|
$this->assertSame('', $this->renderer->processBlockWidgetContent('', [], $widget));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testProcessBlockWidgetContentMultipleH2(): void
|
||
|
|
{
|
||
|
|
$content = '<h2 class="wp-block-heading">First</h2><p>Text</p><h2 class="wp-block-heading">Second</h2>';
|
||
|
|
$widget = new \WP_Widget();
|
||
|
|
|
||
|
|
$result = $this->renderer->processBlockWidgetContent($content, [], $widget);
|
||
|
|
|
||
|
|
$this->assertSame(0, substr_count($result, '<h2'));
|
||
|
|
$this->assertSame(2, substr_count($result, '<h4'));
|
||
|
|
}
|
||
|
|
|
||
|
|
// ── helpers ─────────────────────────────────────────────────
|
||
|
|
|
||
|
|
private function makeParams(string $widgetId, string $classes): array
|
||
|
|
{
|
||
|
|
return [
|
||
|
|
[
|
||
|
|
'widget_id' => $widgetId,
|
||
|
|
'before_widget' => sprintf('<div id="%s" class="%s">', $widgetId, $classes),
|
||
|
|
'after_widget' => '</div>',
|
||
|
|
'before_title' => '<h3 class="sidebar-heading">',
|
||
|
|
'after_title' => '</h3>',
|
||
|
|
],
|
||
|
|
];
|
||
|
|
}
|
||
|
|
}
|