parse(DiviFixtures::markup('stage3/page--globale-instanzen.html'))) ->find($id); } private static function libraryRoot(string $file): Block { return LibraryContent::roots(LibraryContent::load(new Parser(), DiviFixtures::markup('stage3/' . $file)))[0]; } /** @return array Fixture role => [node source, global]. */ public static function builderEntries(): array { return [ 'library--library-abschnitt' => ['page:s1', false], 'library--library-zeile' => ['page:s1.r0', false], 'library--library-modul' => ['page:s1.r0.c0.m0', false], 'library-global--globaler-abschnitt' => ['library:library-global--globaler-abschnitt.html', true], 'library-global--globales-modul' => ['library:library-global--globales-modul.html', true], ]; } /** * Terms and meta as Divi's own "add to library" wrote them (fixtures stage3, JSON of each entry), * without Divi's broken _et_pb_row_layout ("[object Object]", finding 5). * * @dataProvider builderEntries */ public function testTermsAndMetaMatchTheBuilderEntries(string $source, bool $global): void { [$kind, $ref] = explode(':', $source, 2); $node = $kind === 'page' ? self::pageNode($ref) : self::libraryRoot($ref); $role = (string) $this->dataName(); $json = json_decode(DiviFixtures::markup('stage3/' . $role . '.json'), true); $spec = LibraryItemSpec::forNode($node, DiviFixtures::catalog(), 'Titel', $global, 'page'); self::assertInstanceOf(LibraryItemSpec::class, $spec); $expectedTerms = []; foreach (['scope', 'layout_type', 'module_width'] as $taxonomy) { $expectedTerms[$taxonomy] = array_column($json['terms'][$taxonomy], 'slug'); } self::assertEquals($expectedTerms, $spec->terms()); $expectedMeta = array_map(static fn (array $values): string => $values[0], $json['meta']); unset($expectedMeta['_et_pb_row_layout']); self::assertEquals($expectedMeta, $spec->meta()); } public function testRefusesInstancesColumnsAndGlobalsInsideGlobals(): void { $catalog = DiviFixtures::catalog(); self::assertStringContainsString( 'bereits ein globales Modul (Bibliothekseintrag 1058)', (string) LibraryItemSpec::forNode(self::pageNode('g0'), $catalog, 'T', false, 'page') ); self::assertStringContainsString( 'nur Abschnitte, Zeilen und Module', (string) LibraryItemSpec::forNode(self::pageNode('s1.r0.c0'), $catalog, 'T', false, 'page') ); self::assertStringContainsString( 'keine globalen Module', (string) LibraryItemSpec::forNode(self::pageNode('s0'), $catalog, 'T', true, 'page') ); self::assertInstanceOf(LibraryItemSpec::class, LibraryItemSpec::forNode(self::pageNode('s0'), $catalog, 'T', false, 'page')); } /** Ruling P11: opaque roots and instances without a readable id are refused before wrapping. */ public function testRefusesOpaqueRootsAndUnreadableInstances(): void { $catalog = DiviFixtures::catalog(); $document = (new Parser())->parse( '' . '' ); [$opaque, $instance] = $document->children(); self::assertTrue($opaque->isOpaque()); self::assertStringContainsString('nicht lesbar', (string) LibraryItemSpec::forNode($opaque, $catalog, 'T', false, 'page')); self::assertStringContainsString( 'globales Modul', (string) LibraryItemSpec::forNode($instance, $catalog, 'T', false, 'page') ); } public function testFullwidthAndTerms(): void { $section = Block::create('divi/section', ['module' => ['advanced' => ['type' => ['desktop' => ['value' => 'fullwidth']]]]]); $spec = LibraryItemSpec::forNode($section, DiviFixtures::catalog(), 'Kopf', false, 'page'); self::assertSame(['fullwidth'], $spec->terms()['module_width']); self::assertSame([26], $spec->withTerms([26], [])->terms()['layout_category']); self::assertArrayNotHasKey('layout_tag', $spec->withTerms([26], [])->terms()); } }