Files
WP-LIT-MCP/tests/Unit/Integrations/Divi/Release/DiviFeatureAssignmentTest.php
T

198 lines
9.4 KiB
PHP

<?php
declare(strict_types=1);
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Release;
use LIT\MCP\Integrations\Divi\Design\DesignSystemReader;
use LIT\MCP\Integrations\Divi\Design\DesignSystemWriter;
use LIT\MCP\Integrations\Divi\Design\FontCatalog;
use LIT\MCP\Integrations\Divi\Design\GlobalColorsAdapter;
use LIT\MCP\Integrations\Divi\Design\GlobalVariablesAdapter;
use LIT\MCP\Integrations\Divi\Design\ThemeOptionsAdapter;
use LIT\MCP\Integrations\Divi\Library\DiviLibraryStore;
use LIT\MCP\Integrations\Divi\Library\DiviRoles;
use LIT\MCP\Integrations\Divi\Pages\DiviPages;
use LIT\MCP\Integrations\Divi\Pages\DynamicContentMap;
use LIT\MCP\Integrations\Divi\Release\DiviAdapters;
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
use LIT\MCP\Integrations\Divi\Release\Mirror;
use LIT\MCP\Integrations\Divi\Schema\DiviModules;
use LIT\MCP\Integrations\Divi\ThemeBuilder\DiviThemeBuilder;
use PHPUnit\Framework\TestCase;
/**
* Every manifest entry of every adapter names the Divi features it serves (D2 of the plan "Divi-Fähigkeiten"), and
* the assignment is pinned here: a changed tag shows up in review as a changed row of this table.
*/
final class DiviFeatureAssignmentTest extends TestCase
{
/** Adapter => requirement ("Nachbau " before a mirror's label) => features (sorted values). */
private const EXPECTED = [
DiviPages::class => [
'ET_Core_PageResource::remove_static_resources()' => ['page-write', 'tb-write'],
'et_builder_get_public_post_types()' => ['page-write'],
'Nachbau SyncToServerController::update()' => ['page-write'],
],
DiviLibraryStore::class => [
'GlobalLayout::is_global_layout_template()' => ['library-read', 'library-write'],
'Nachbau et_pb_submit_layout()' => ['library-write'],
],
DiviRoles::class => [
'et_pb_is_allowed()' => ['roles'],
],
DiviThemeBuilder::class => [
'et_theme_builder_get_theme_builder_post_id()' => ['tb-read', 'tb-write'],
'et_theme_builder_get_theme_builder_template_ids()' => ['tb-read'],
'et_theme_builder_get_template()' => ['tb-read'],
'et_theme_builder_insert_layout()' => ['tb-write'],
'et_theme_builder_store_template()' => ['tb-write'],
'et_theme_builder_get_flat_template_settings_options()' => ['tb-read'],
'et_theme_builder_clear_wp_cache()' => ['page-write', 'tb-write'],
'et_()' => ['tb-write'],
'ET_Core_PageResource::remove_static_resources()' => ['page-write', 'tb-write'],
'Nachbau et_theme_builder_api_save()' => ['tb-write'],
'Nachbau et_theme_builder_store_template()' => ['tb-write'],
'Nachbau et_theme_builder_load_template_setting_options()' => ['tb-read', 'tb-write'],
],
DesignSystemReader::class => [
'GlobalData::get_global_colors()' => ['design-read', 'page-read'],
'GlobalData::get_global_variables()' => ['design-read', 'page-read'],
'GlobalPreset::get_data()' => ['design-read', 'page-read'],
],
DesignSystemWriter::class => [
'GlobalPreset::get_data()' => ['design-read', 'preset-write'],
'GlobalPreset::prepare_data()' => ['preset-write'],
'GlobalPreset::validate_preset_count()' => ['preset-write'],
'GlobalPreset::get_deleted_preset_ids()' => ['preset-write'],
'GlobalPreset::remove_preset_from_legacy_option()' => ['preset-write'],
'GlobalPreset::save_data()' => ['preset-write'],
'Conversion::get_preset_attrs_mapping()' => ['preset-write'],
'Conversion::get_preset_attrs()' => ['preset-write'],
'GlobalPreset::get_group_preset_default_attr()' => ['catalog', 'preset-write'],
'ModuleRegistration::get_module_settings()' => ['catalog', 'preset-write'],
'UserRole::can_current_user_use_visual_builder()' => ['preset-write'],
'Nachbau GlobalPresetController::sync()' => ['preset-write'],
],
GlobalColorsAdapter::class => [
'GlobalData::get_global_colors()' => ['color-write'],
'GlobalData::sanitize_global_colors_data()' => ['color-write'],
'GlobalData::set_global_colors()' => ['color-write'],
],
GlobalVariablesAdapter::class => [
'GlobalData::get_global_variables()' => ['variable-write'],
'GlobalData::set_global_variables()' => ['variable-write'],
'et_pb_is_allowed()' => ['variable-write'],
],
ThemeOptionsAdapter::class => [
'et_sanitize_font_choices()' => ['theme-option-write'],
'et_sanitize_global_font_weight()' => ['theme-option-write'],
'et_sanitize_float_number()' => ['theme-option-write'],
'et_sanitize_int_number()' => ['theme-option-write'],
'et_divi_global_font_style()' => ['theme-option-write'],
'et_update_option()' => ['theme-option-write'],
'et_delete_option()' => ['theme-option-write'],
'ET_Core_PageResource::remove_static_resources()' => ['theme-option-write'],
'et_pb_force_regenerate_templates()' => ['theme-option-write'],
'et_pb_is_allowed()' => ['theme-option-write'],
'Nachbau et_divi_customizer_theme_settings()' => ['theme-option-read', 'theme-option-write'],
],
FontCatalog::class => [
'et_builder_get_fonts()' => ['font-upload', 'theme-option-write', 'variable-write'],
'et_builder_get_custom_fonts()' => ['font-upload', 'theme-option-write', 'variable-write'],
'et_builder_get_google_fonts()' => ['font-upload', 'theme-option-write', 'variable-write'],
'et_builder_get_websafe_fonts()' => ['font-upload', 'theme-option-write', 'variable-write'],
'et_pb_is_allowed()' => ['font-upload'],
],
DiviModules::class => [
'ModuleRegistration::get_all_core_modules_metadata()' => ['catalog'],
'ModuleRegistration::get_default_attrs()' => ['catalog'],
'et_builder_enabled_for_post_type()' => ['catalog'],
'Konstante ET_BUILDER_PRODUCT_VERSION' => ['catalog'],
],
DynamicContentMap::class => [
'DynamicContentOptions::get_options()' => ['dynamic-sources'],
],
];
public function testEveryRequirementOfEveryAdapterServesAtLeastOneFeature(): void
{
$bare = [];
foreach (DiviAdapters::manifests() as $class => $manifest) {
foreach ($manifest->requirements() as $requirement) {
$features = $manifest->featuresOf($requirement);
if ($features === [] || array_unique($features, SORT_REGULAR) !== $features) {
$bare[] = $class . ': ' . $requirement->label();
}
}
}
self::assertSame([], $bare, "Anforderungen ohne (eindeutige) Fähigkeit:\n" . implode("\n", $bare));
}
public function testEveryFeatureIsServedByAtLeastOneRequirement(): void
{
$served = [];
foreach (DiviAdapters::manifests() as $manifest) {
foreach ($manifest->requirements() as $requirement) {
foreach ($manifest->featuresOf($requirement) as $feature) {
$served[$feature->value] = true;
}
}
}
$missing = array_values(array_diff(
array_map(static fn (DiviFeature $feature): string => $feature->value, DiviFeature::cases()),
array_keys($served)
));
self::assertSame([], $missing, 'Fähigkeiten ohne Anforderung in einem Manifest');
}
public function testTheAssignmentIsThePinnedTable(): void
{
$actual = [];
foreach (DiviAdapters::manifests() as $class => $manifest) {
foreach ($manifest->requirements() as $requirement) {
$values = array_map(
static fn (DiviFeature $feature): string => $feature->value,
$manifest->featuresOf($requirement)
);
sort($values);
$name = ($requirement instanceof Mirror ? 'Nachbau ' : '') . $requirement->label();
$actual[$class][$name] = $values;
}
}
self::assertSame(self::EXPECTED, $actual);
self::assertSame(array_keys(self::EXPECTED), DiviAdapters::CLASSES, 'all twelve adapters, in report order');
}
public function testReadingAdaptersCarryNoWriteFeature(): void
{
$readingOnly = [DesignSystemReader::class, DiviRoles::class, DiviModules::class, DynamicContentMap::class];
foreach ($readingOnly as $class) {
$manifest = DiviAdapters::manifests()[$class];
foreach ($manifest->requirements() as $requirement) {
foreach ($manifest->featuresOf($requirement) as $feature) {
self::assertFalse($feature->isWrite(), $class . ': ' . $requirement->label());
}
}
}
}
public function testEveryMirrorServesAWriteFeature(): void
{
foreach (DiviAdapters::manifests() as $class => $manifest) {
foreach ($manifest->mirrors as $mirror) {
$writes = array_filter(
$manifest->featuresOf($mirror),
static fn (DiviFeature $feature): bool => $feature->isWrite()
);
self::assertNotSame([], $writes, $class . ': Nachbau ' . $mirror->id . ' dient keinem Schreib-Feature');
}
}
}
}