Both forms Divi writes are recognized (ruling Q11): custom_meta_<key> and the dialog form post_meta_key + select_meta_key. Choice fields get a note about the stored value, relation fields name IDs (F4). Only templates the user may edit are checked or named; others are counted (Q21 pattern). Warnings only, also in the dry run of a live body. DynamicFields extracted from lit/divi-dynamic-sources. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
111 lines
4.8 KiB
PHP
111 lines
4.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Pages;
|
|
|
|
use LIT\MCP\Integrations\Divi\Compose\VariableRef;
|
|
use LIT\MCP\Integrations\Divi\Pages\DynamicFields;
|
|
use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
|
use LIT\MCP\Integrations\WordPress\Schema\FieldDefinition;
|
|
use LIT\MCP\Tests\Support\DiviFixtures;
|
|
use LIT\MCP\Tests\Unit\TestCase;
|
|
use Mockery;
|
|
|
|
final class DynamicFieldsTest extends TestCase
|
|
{
|
|
private static function fields(): DynamicFields
|
|
{
|
|
$schema = Mockery::mock(ContentSchema::class);
|
|
$schema->allows('fields')->with('lit_person')->andReturn([
|
|
new FieldDefinition('role', 'Funktion', 'string', 'pods', FieldDefinition::WRITABLE),
|
|
new FieldDefinition('level', 'Stufe', 'choice', 'pods', FieldDefinition::WRITABLE),
|
|
new FieldDefinition('mentor', 'Mentor', 'relation', 'pods', FieldDefinition::WRITABLE),
|
|
]);
|
|
|
|
return new DynamicFields($schema, static fn (string $type): ?string => 'meta');
|
|
}
|
|
|
|
public function testTextLikeFieldsAreOfferedOthersOmittedWithTheirReason(): void
|
|
{
|
|
[$offered, $omitted] = self::fields()->offered('lit_person');
|
|
|
|
self::assertSame(['role', 'level'], array_column($offered, 'key'));
|
|
self::assertSame('{{field:role}}', $offered[0]['placeholder']);
|
|
self::assertSame(['mentor'], array_column($omitted, 'key'));
|
|
}
|
|
|
|
public function testReasonForOneKey(): void
|
|
{
|
|
self::assertNull(self::fields()->reason('lit_person', 'role'));
|
|
self::assertStringContainsString('nur IDs', (string) self::fields()->reason('lit_person', 'mentor'));
|
|
self::assertSame('kein bekanntes Feld dieses Inhaltstyps', self::fields()->reason('lit_person', 'telefon'));
|
|
}
|
|
|
|
/** Answer F4 / stage3b render: a choice field shows its stored value ("senior"), not the label. */
|
|
public function testChoiceFieldsGetANoteAboutTheStoredValue(): void
|
|
{
|
|
self::assertStringContainsString('gespeicherten Wert', (string) self::fields()->note('lit_person', 'level'));
|
|
self::assertNull(self::fields()->note('lit_person', 'role'));
|
|
self::assertNull(self::fields()->note('lit_person', 'mentor'));
|
|
self::assertNull(self::fields()->note('lit_person', 'telefon'));
|
|
}
|
|
|
|
private static function content(string $name, array $settings): string
|
|
{
|
|
return VariableRef::serialize('content', $name, $settings);
|
|
}
|
|
|
|
/** Ruling Q11 / stage3b finding 12: both forms Divi resolves (DynamicContentOptionPostMetaKey.php:222-262). */
|
|
public function testMetaKeyOfReadsBothFormsDiviWrites(): void
|
|
{
|
|
self::assertSame('role', DynamicFields::metaKeyOf(self::content('custom_meta_role', ['before' => ''])));
|
|
self::assertSame('role', DynamicFields::metaKeyOf(self::content('post_meta_key', [
|
|
'before' => '',
|
|
'after' => '',
|
|
'select_meta_key' => 'custom_meta_role',
|
|
'meta_key' => '',
|
|
'date_format' => 'default',
|
|
'custom_date_format' => '',
|
|
'enable_html' => 'off',
|
|
])));
|
|
self::assertSame('telefon', DynamicFields::metaKeyOf(self::content('post_meta_key', ['meta_key' => 'telefon'])));
|
|
self::assertSame('telefon', DynamicFields::metaKeyOf(self::content('post_meta_key', [
|
|
'select_meta_key' => 'custom_meta_manual_custom_field_value',
|
|
'meta_key' => 'telefon',
|
|
])));
|
|
self::assertSame('telefon', DynamicFields::metaKeyOf(self::content(
|
|
'custom_meta_manual_custom_field_value',
|
|
['meta_key' => 'telefon']
|
|
)));
|
|
}
|
|
|
|
public function testMetaKeyOfIgnoresEverythingElse(): void
|
|
{
|
|
self::assertNull(DynamicFields::metaKeyOf(self::content('post_title', ['before' => ''])));
|
|
self::assertNull(DynamicFields::metaKeyOf(self::content('post_meta_key', ['meta_key' => ''])));
|
|
self::assertNull(DynamicFields::metaKeyOf(self::content('post_meta_key', ['select_meta_key' => 'role'])));
|
|
self::assertNull(DynamicFields::metaKeyOf(self::content('custom_meta_', [])));
|
|
self::assertNull(DynamicFields::metaKeyOf(
|
|
'$variable({"type":"color","value":{"name":"custom_meta_role","settings":{}}})$'
|
|
));
|
|
self::assertNull(DynamicFields::metaKeyOf('custom_meta_role'));
|
|
}
|
|
|
|
/** The real builder output (stage3b body 2391) names role, level and mentor. */
|
|
public function testMetaKeysOfTheRealBuilderBody(): void
|
|
{
|
|
$content = DiviFixtures::markup('stage3b/tb-body--person-body.html');
|
|
preg_match_all('/"value":"(\$variable\(.*?\)\$)"/', $content, $matches);
|
|
$keys = [];
|
|
foreach ($matches[1] as $value) {
|
|
$key = DynamicFields::metaKeyOf((string) json_decode('"' . $value . '"'));
|
|
if ($key !== null) {
|
|
$keys[] = $key;
|
|
}
|
|
}
|
|
|
|
self::assertSame(['role', 'level', 'mentor'], $keys);
|
|
}
|
|
}
|