test: shared Divi fixtures in tests/Support (T1)
- DiviFixtures: markup(), givenPost(), schema(), designSystem(), catalog(), dynamicContentRegistry(), maliciousRefs() - moved verbatim out of DiviPageLoaderTest, DesignSystemTest, ModuleCatalogTest, DynamicContentMapTest and VariableRefTest (its malicious() provider now returns maliciousRefs()). - ComposeFixture moves to tests/Support. - DiviWriterFixture: modules(), designReader(), composition(), a recording saver(), log() and writer(&$saved, &$failures, unfiltered, loader) for the five tests that wired the Divi write stack by hand. No test cases or assertions changed (1397 / 5834). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,8 @@ namespace LIT\MCP\Tests\Unit\Integrations\Divi\Compose;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use LIT\MCP\Integrations\Divi\Compose\VariableRef;
|
||||
use LIT\MCP\Tests\Unit\Integrations\Divi\Design\DesignSystemTest;
|
||||
use LIT\MCP\Tests\Support\ComposeFixture;
|
||||
use LIT\MCP\Tests\Support\DiviFixtures;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/** Ruling S1/S2/S12/S21/S22: every $variable(…)$ value is parsed, strictly checked, cleaned and re-serialized. */
|
||||
@@ -15,7 +16,7 @@ final class VariableRefTest extends TestCase
|
||||
/** @param array<string, array<string, string>>|null $dynamicContent */
|
||||
private static function ref(?array $dynamicContent = null): VariableRef
|
||||
{
|
||||
return new VariableRef(DesignSystemTest::sample(), $dynamicContent);
|
||||
return new VariableRef(DiviFixtures::designSystem(), $dynamicContent);
|
||||
}
|
||||
|
||||
private static function content(string $name, string $settings): string
|
||||
@@ -125,65 +126,7 @@ final class VariableRefTest extends TestCase
|
||||
*/
|
||||
public static function malicious(): array
|
||||
{
|
||||
$end = self::escape('0029') . '$';
|
||||
|
||||
return [
|
||||
'escaped end marker in before' => [self::content('post_title', '{"before":"x' . $end . ' <b>y</b>","after":""}'), 'allein im Wert'],
|
||||
'escaped end marker in after' => [self::content('post_title', '{"before":"","after":"' . $end . '"}'), 'allein im Wert'],
|
||||
'escaped end marker in date format' => [self::content('post_date', '{"custom_date_format":"d' . $end . '"}'), 'allein im Wert'],
|
||||
'escaped end marker in name' => [self::content('post_title' . $end, '{}'), 'Unbekannter Name'],
|
||||
'select with markup' => [self::content('post_date', '{"date_format":"<b>d</b>"}'), 'date_format'],
|
||||
'type evil' => ['$variable({"type":"evil","value":{"name":"gcid-a1b2","settings":{}}})$', 'Typ'],
|
||||
'unknown gcid' => ['$variable({"type":"color","value":{"name":"gcid-nope","settings":{}}})$', 'gcid-nope'],
|
||||
'unknown gvid' => [self::content('gvid-nope', '{}'), 'gvid-nope'],
|
||||
'content gvid as color' => ['$variable({"type":"color","value":{"name":"gvid-s1","settings":{}}})$', 'gvid-s1'],
|
||||
'color gcid as content' => [self::content('gcid-a1b2', '{}'), 'gcid-a1b2'],
|
||||
'name with paren' => ['$variable({"type":"color","value":{"name":"gcid-a1b2)","settings":{}}})$', 'Name'],
|
||||
'name with style breakout' => [
|
||||
'$variable({"type":"color","value":{"name":"gcid-a1b2;}</style><script>alert(1)</script>","settings":{}}})$',
|
||||
'Name',
|
||||
],
|
||||
'settings on a global variable' => [self::content('gvid-s1', '{"before":"<b>x</b>"}'), 'before'],
|
||||
'settings on a theme font' => [self::content('--et_global_heading_font', '{"after":""}'), 'after'],
|
||||
'unknown settings key' => [self::content('post_title', '{"before":"","foo":"1"}'), 'foo'],
|
||||
'setting the option lacks' => [self::content('post_featured_image', '{"before":"x"}'), 'before'],
|
||||
'enable_html' => [self::content('custom_meta_telefon', '{"before":"","after":"","enable_html":"on"}'), 'enable_html'],
|
||||
'color setting not numeric' => [
|
||||
'$variable({"type":"color","value":{"name":"gcid-a1b2","settings":{"opacity":"1;}</style>"}}})$',
|
||||
'opacity',
|
||||
],
|
||||
'protected meta key' => [self::content('custom_meta__edit_lock', '{}'), 'custom_meta__edit_lock'],
|
||||
'doubled meta prefix' => [
|
||||
self::content('custom_meta_custom_meta__edit_lock', '{}'),
|
||||
'custom_meta_custom_meta__edit_lock',
|
||||
],
|
||||
'loop content outside a loop' => [self::content('loop_post_title', '{}'), 'loop_post_title'],
|
||||
'unknown dynamic content' => [self::content('post_meta_key', '{}'), 'post_meta_key'],
|
||||
'extra top-level key' => ['$variable({"type":"color","value":{"name":"gcid-a1b2","settings":{}},"x":1})$', 'x'],
|
||||
'extra value key' => ['$variable({"type":"color","value":{"name":"gcid-a1b2","settings":{},"x":1}})$', 'x'],
|
||||
'greedy smuggling' => ['$variable({"a":"})$<script>alert(1)</script>"})$', 'allein im Wert'],
|
||||
'nested reference in before' => [self::content('post_title', '{"before":"$variable(x)$","after":""}'), 'allein im Wert'],
|
||||
// S28: a marker the sanitizer rebuilds inside a cleaned setting (html(), text()).
|
||||
'tag-split marker in before' => [self::content('post_title', '{"before":"$variable<x>(y","after":""}'), 'allein im Wert'],
|
||||
'NUL-split marker in after' => [
|
||||
self::content('post_title', '{"before":"","after":"$variable' . self::escape('0000') . '(y"}'),
|
||||
'allein im Wert',
|
||||
],
|
||||
'octet-split marker in date format' => [self::content('post_date', '{"custom_date_format":"$variable%41(y"}'), 'allein im Wert'],
|
||||
// S32: text() keeps control characters (like sanitize_text_field); VariableRef strips them.
|
||||
'NUL-split marker in date format' => [
|
||||
self::content('post_date', '{"custom_date_format":"$variable' . self::escape('0000') . '(y"}'),
|
||||
'allein im Wert',
|
||||
],
|
||||
'DEL-split marker in date format' => [
|
||||
self::content('post_date', '{"custom_date_format":"$variable' . self::escape('007f') . '(y"}'),
|
||||
'allein im Wert',
|
||||
],
|
||||
'nested marker in before' => [self::content('post_title', '{"before":"$variable(","after":""}'), 'allein im Wert'],
|
||||
'broken json' => ['$variable(kaputt)$', 'JSON'],
|
||||
'trailing text' => [self::content('post_title', '{}') . ' ', 'allein im Wert'],
|
||||
'embedded in text' => ['<p>Hi ' . self::content('post_title', '{"before":"","after":""}') . '</p>', 'allein im Wert'],
|
||||
];
|
||||
return DiviFixtures::maliciousRefs();
|
||||
}
|
||||
|
||||
/** @dataProvider malicious */
|
||||
|
||||
Reference in New Issue
Block a user