Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
153 lines
6.4 KiB
PHP
153 lines
6.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace LIT\MCP\Tests\Unit\Integrations\WordPress\Schema;
|
|
|
|
use Brain\Monkey\Functions;
|
|
use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
|
use LIT\MCP\Integrations\WordPress\Schema\FieldDefinition;
|
|
use LIT\MCP\Integrations\WordPress\Schema\FieldSource;
|
|
use LIT\MCP\Tests\Unit\TestCase;
|
|
use Mockery;
|
|
|
|
final class ContentSchemaTest extends TestCase
|
|
{
|
|
private function source(string $id, array $fields): FieldSource
|
|
{
|
|
$source = Mockery::mock(FieldSource::class);
|
|
$source->allows('id')->andReturn($id);
|
|
$source->allows('fieldsFor')->andReturn($fields);
|
|
|
|
return $source;
|
|
}
|
|
|
|
private function stubPostTypes(): void
|
|
{
|
|
Functions\when('get_post_types')->justReturn([
|
|
'post' => 'post',
|
|
'page' => 'page',
|
|
'attachment' => 'attachment',
|
|
'et_pb_layout' => 'et_pb_layout',
|
|
'lit_person' => 'lit_person',
|
|
]);
|
|
}
|
|
|
|
public function testPostTypeNamesExcludeInternalTypesAndAreSorted(): void
|
|
{
|
|
$this->stubPostTypes();
|
|
|
|
$schema = new ContentSchema([], null, ['et_pb_layout']);
|
|
|
|
self::assertSame(['lit_person', 'page', 'post'], $schema->postTypeNames());
|
|
self::assertTrue($schema->isManaged('page'));
|
|
self::assertFalse($schema->isManaged('et_pb_layout'));
|
|
}
|
|
|
|
public function testFieldsAreMergedByPriorityAndSorted(): void
|
|
{
|
|
$pods = $this->source('pods', [new FieldDefinition('role', 'Funktion', 'string', 'pods', 'writable', true)]);
|
|
$meta = $this->source('sample', [
|
|
new FieldDefinition('role', 'role', 'unknown', 'sample', 'unknown'),
|
|
new FieldDefinition('city', 'city', 'unknown', 'sample', 'unknown'),
|
|
]);
|
|
$schema = new ContentSchema([$pods, $meta]);
|
|
|
|
$fields = $schema->fields('lit_person');
|
|
|
|
self::assertSame(['city', 'role'], array_keys($fields));
|
|
self::assertSame('pods', $fields['role']->source);
|
|
self::assertTrue($fields['role']->required);
|
|
self::assertSame($pods, $schema->sourceOf($fields['role']));
|
|
self::assertSame($meta, $schema->sourceOf($fields['city']));
|
|
}
|
|
|
|
public function testDescribeIncludesTaxonomiesCountsDiviAndOptionalFields(): void
|
|
{
|
|
$this->stubPostTypes();
|
|
Functions\when('get_post_type_object')->justReturn((object) [
|
|
'hierarchical' => true,
|
|
'labels' => (object) ['name' => 'Seiten', 'singular_name' => 'Seite'],
|
|
]);
|
|
Functions\when('get_all_post_type_supports')->justReturn(['title' => true, 'editor' => true]);
|
|
Functions\when('wp_count_posts')->justReturn((object) ['publish' => 3, 'draft' => 2, 'trash' => 9]);
|
|
Functions\when('get_object_taxonomies')->justReturn([
|
|
(object) ['name' => 'category', 'show_ui' => true, 'hierarchical' => true, 'labels' => (object) ['name' => 'Kategorien']],
|
|
(object) ['name' => 'post_format', 'show_ui' => false, 'hierarchical' => false, 'labels' => (object) ['name' => 'Formate']],
|
|
]);
|
|
$schema = new ContentSchema(
|
|
[$this->source('meta', [
|
|
new FieldDefinition('footnotes', 'footnotes', 'string', 'meta', 'writable'),
|
|
new FieldDefinition('zz_hidden', 'Verborgen', 'string', 'pods', FieldDefinition::HIDDEN),
|
|
])],
|
|
static fn (string $type): bool => $type === 'page',
|
|
['et_pb_layout']
|
|
);
|
|
|
|
$withoutFields = $schema->describe('page', false);
|
|
$withFields = $schema->describe('page', true);
|
|
|
|
self::assertSame('Seiten', $withoutFields['label']);
|
|
self::assertSame('Seite', $withoutFields['singular_label']);
|
|
self::assertTrue($withoutFields['hierarchical']);
|
|
self::assertSame(['title', 'editor'], $withoutFields['supports']);
|
|
self::assertTrue($withoutFields['divi']);
|
|
self::assertSame(5, $withoutFields['count']);
|
|
self::assertSame([['name' => 'category', 'label' => 'Kategorien', 'hierarchical' => true]], $withoutFields['taxonomies']);
|
|
self::assertArrayNotHasKey('fields', $withoutFields);
|
|
self::assertSame('footnotes', $withFields['fields'][0]['key']);
|
|
self::assertCount(1, $withFields['fields'], 'hidden (restricted) fields are not described (M4)');
|
|
self::assertNull($schema->describe('et_pb_layout', false));
|
|
}
|
|
|
|
public function testMediaFieldKeysCoverFileFieldsAndMediaRelations(): void
|
|
{
|
|
Functions\when('get_post_types')->justReturn(['page' => 'page', 'lit_person' => 'lit_person']);
|
|
$source = Mockery::mock(FieldSource::class);
|
|
$source->allows('id')->andReturn('pods');
|
|
$source->allows('fieldsFor')->andReturnUsing(static fn (string $type): array => $type === 'lit_person'
|
|
? [
|
|
new FieldDefinition('photo', 'Foto', 'file', 'pods', 'writable'),
|
|
new FieldDefinition('logo', 'Logo', 'relation', 'pods', 'writable', false, false, null, [
|
|
'object_type' => 'media',
|
|
'name' => null,
|
|
]),
|
|
new FieldDefinition('role', 'Funktion', 'string', 'pods', 'writable'),
|
|
]
|
|
: [new FieldDefinition('photo', 'Foto', 'file', 'pods', 'writable')]);
|
|
|
|
self::assertSame(['logo', 'photo'], (new ContentSchema([$source]))->mediaFieldKeys());
|
|
}
|
|
|
|
public function testWordPressExcludesItsOwnPostTypesAndIntegrationsAddTheirs(): void
|
|
{
|
|
$this->stubPostTypes();
|
|
|
|
self::assertSame(
|
|
['et_pb_layout', 'lit_person', 'page', 'post'],
|
|
(new ContentSchema([]))->postTypeNames(),
|
|
'without an integration the Divi layouts are an ordinary post type'
|
|
);
|
|
self::assertSame(
|
|
['page', 'post'],
|
|
(new ContentSchema([], null, ['et_pb_layout', 'lit_person']))->postTypeNames()
|
|
);
|
|
self::assertSame(
|
|
[
|
|
'attachment', 'nav_menu_item', 'revision', 'wp_block', 'wp_template', 'wp_template_part',
|
|
'wp_navigation', 'wp_global_styles', 'wp_font_family', 'wp_font_face',
|
|
],
|
|
ContentSchema::EXCLUDED
|
|
);
|
|
}
|
|
|
|
public function testTheBuilderIsNeverOnWithoutACheck(): void
|
|
{
|
|
self::assertFalse((new ContentSchema([]))->diviEnabled('page'));
|
|
$schema = new ContentSchema([], static fn (string $type): bool => $type === 'page');
|
|
|
|
self::assertTrue($schema->diviEnabled('page'));
|
|
self::assertFalse($schema->diviEnabled('post'));
|
|
}
|
|
}
|