function BubbleableMetadataTest::testMergeAttachmentsLibraryMerging

Same name in other branches
  1. 8.9.x core/tests/Drupal/Tests/Core/Render/BubbleableMetadataTest.php \Drupal\Tests\Core\Render\BubbleableMetadataTest::testMergeAttachmentsLibraryMerging()
  2. 10 core/tests/Drupal/Tests/Core/Render/BubbleableMetadataTest.php \Drupal\Tests\Core\Render\BubbleableMetadataTest::testMergeAttachmentsLibraryMerging()
  3. 11.x core/tests/Drupal/Tests/Core/Render/BubbleableMetadataTest.php \Drupal\Tests\Core\Render\BubbleableMetadataTest::testMergeAttachmentsLibraryMerging()

Tests library asset merging.

@covers ::mergeAttachments

File

core/tests/Drupal/Tests/Core/Render/BubbleableMetadataTest.php, line 239

Class

BubbleableMetadataTest
@coversDefaultClass \Drupal\Core\Render\BubbleableMetadata @group Render

Namespace

Drupal\Tests\Core\Render

Code

public function testMergeAttachmentsLibraryMerging() {
    $a['#attached'] = [
        'library' => [
            'core/drupal',
            'core/drupalSettings',
        ],
        'drupalSettings' => [
            'foo' => [
                'd',
            ],
        ],
    ];
    $b['#attached'] = [
        'library' => [
            'core/jquery',
        ],
        'drupalSettings' => [
            'bar' => [
                'a',
                'b',
                'c',
            ],
        ],
    ];
    $expected['#attached'] = [
        'library' => [
            'core/drupal',
            'core/drupalSettings',
            'core/jquery',
        ],
        'drupalSettings' => [
            'foo' => [
                'd',
            ],
            'bar' => [
                'a',
                'b',
                'c',
            ],
        ],
    ];
    $this->assertSame($expected['#attached'], BubbleableMetadata::mergeAttachments($a['#attached'], $b['#attached']), 'Attachments merged correctly.');
    // Merging in the opposite direction yields the opposite library order.
    $expected['#attached'] = [
        'library' => [
            'core/jquery',
            'core/drupal',
            'core/drupalSettings',
        ],
        'drupalSettings' => [
            'bar' => [
                'a',
                'b',
                'c',
            ],
            'foo' => [
                'd',
            ],
        ],
    ];
    $this->assertSame($expected['#attached'], BubbleableMetadata::mergeAttachments($b['#attached'], $a['#attached']), 'Attachments merged correctly; opposite merging yields opposite order.');
    // Merging with duplicates: duplicates are simply retained, it's up to the
    // rest of the system to handle duplicates.
    $b['#attached']['library'][] = 'core/drupalSettings';
    $expected['#attached'] = [
        'library' => [
            'core/drupal',
            'core/drupalSettings',
            'core/jquery',
            'core/drupalSettings',
        ],
        'drupalSettings' => [
            'foo' => [
                'd',
            ],
            'bar' => [
                'a',
                'b',
                'c',
            ],
        ],
    ];
    $this->assertSame($expected['#attached'], BubbleableMetadata::mergeAttachments($a['#attached'], $b['#attached']), 'Attachments merged correctly; duplicates are retained.');
    // Merging with duplicates (simple case).
    $b['#attached']['drupalSettings']['foo'] = [
        'a',
        'b',
        'c',
    ];
    $expected['#attached'] = [
        'library' => [
            'core/drupal',
            'core/drupalSettings',
            'core/jquery',
            'core/drupalSettings',
        ],
        'drupalSettings' => [
            'foo' => [
                'a',
                'b',
                'c',
            ],
            'bar' => [
                'a',
                'b',
                'c',
            ],
        ],
    ];
    $this->assertSame($expected['#attached'], BubbleableMetadata::mergeAttachments($a['#attached'], $b['#attached']));
    // Merging with duplicates (simple case) in the opposite direction yields
    // the opposite JS setting asset order, but also opposite overriding order.
    $expected['#attached'] = [
        'library' => [
            'core/jquery',
            'core/drupalSettings',
            'core/drupal',
            'core/drupalSettings',
        ],
        'drupalSettings' => [
            'bar' => [
                'a',
                'b',
                'c',
            ],
            'foo' => [
                'd',
                'b',
                'c',
            ],
        ],
    ];
    $this->assertSame($expected['#attached'], BubbleableMetadata::mergeAttachments($b['#attached'], $a['#attached']));
    // Merging with duplicates: complex case.
    // Only the second of these two entries should appear in drupalSettings.
    $build = [];
    $build['a']['#attached']['drupalSettings']['commonTest'] = 'firstValue';
    $build['b']['#attached']['drupalSettings']['commonTest'] = 'secondValue';
    // Only the second of these entries should appear in drupalSettings.
    $build['a']['#attached']['drupalSettings']['commonTestJsArrayLiteral'] = [
        'firstValue',
    ];
    $build['b']['#attached']['drupalSettings']['commonTestJsArrayLiteral'] = [
        'secondValue',
    ];
    // Only the second of these two entries should appear in drupalSettings.
    $build['a']['#attached']['drupalSettings']['commonTestJsObjectLiteral'] = [
        'key' => 'firstValue',
    ];
    $build['b']['#attached']['drupalSettings']['commonTestJsObjectLiteral'] = [
        'key' => 'secondValue',
    ];
    // Real world test case: multiple elements in a render array are adding the
    // same (or nearly the same) JavaScript settings. When merged, they should
    // contain all settings and not duplicate some settings.
    $settings_one = [
        'moduleName' => [
            'ui' => [
                'button A',
                'button B',
            ],
            'magical flag' => 3.14159265359,
        ],
    ];
    $build['a']['#attached']['drupalSettings']['commonTestRealWorldIdentical'] = $settings_one;
    $build['b']['#attached']['drupalSettings']['commonTestRealWorldIdentical'] = $settings_one;
    $settings_two_a = [
        'moduleName' => [
            'ui' => [
                'button A',
                'button B',
                'button C',
            ],
            'magical flag' => 3.14159265359,
            'thingiesOnPage' => [
                'id1' => [],
            ],
        ],
    ];
    $build['a']['#attached']['drupalSettings']['commonTestRealWorldAlmostIdentical'] = $settings_two_a;
    $settings_two_b = [
        'moduleName' => [
            'ui' => [
                'button D',
                'button E',
            ],
            'magical flag' => 3.14,
            'thingiesOnPage' => [
                'id2' => [],
            ],
        ],
    ];
    $build['b']['#attached']['drupalSettings']['commonTestRealWorldAlmostIdentical'] = $settings_two_b;
    $merged = BubbleableMetadata::mergeAttachments($build['a']['#attached'], $build['b']['#attached']);
    // Test whether #attached can be used to override a previous setting.
    $this->assertSame('secondValue', $merged['drupalSettings']['commonTest']);
    // Test whether #attached can be used to add and override a JavaScript
    // array literal (an indexed PHP array) values.
    $this->assertSame('secondValue', $merged['drupalSettings']['commonTestJsArrayLiteral'][0]);
    // Test whether #attached can be used to add and override a JavaScript
    // object literal (an associate PHP array) values.
    $this->assertSame('secondValue', $merged['drupalSettings']['commonTestJsObjectLiteral']['key']);
    // Test whether the two real world cases are handled correctly: the first
    // adds the exact same settings twice and hence tests idempotency, the
    // second adds *almost* the same settings twice: the second time, some
    // values are altered, and some key-value pairs are added.
    $this->assertSame($settings_one, $merged['drupalSettings']['commonTestRealWorldIdentical']);
    $expected_settings_two = $settings_two_a;
    $expected_settings_two['moduleName']['thingiesOnPage']['id1'] = [];
    $expected_settings_two['moduleName']['ui'][0] = 'button D';
    $expected_settings_two['moduleName']['ui'][1] = 'button E';
    $expected_settings_two['moduleName']['ui'][2] = 'button C';
    $expected_settings_two['moduleName']['magical flag'] = 3.14;
    $expected_settings_two['moduleName']['thingiesOnPage']['id2'] = [];
    $this->assertSame($expected_settings_two, $merged['drupalSettings']['commonTestRealWorldAlmostIdentical']);
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.