diff --git a/typo3/sysext/core/Tests/Functional/Page/AssetRendererTest.php b/typo3/sysext/core/Tests/Functional/Page/AssetRendererTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8d4e937482f99e1d6ad5454ba7e1a47e1ebde60b
--- /dev/null
+++ b/typo3/sysext/core/Tests/Functional/Page/AssetRendererTest.php
@@ -0,0 +1,359 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Core\Tests\Functional\Page;
+
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
+use TYPO3\CMS\Core\Page\AssetCollector;
+use TYPO3\CMS\Core\Page\AssetRenderer;
+use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
+
+final class AssetRendererTest extends FunctionalTestCase
+{
+    protected bool $resetSingletonInstances = true;
+
+    protected array $configurationToUseInTestInstance = [
+        'BE' => [
+            'versionNumberInFilename' => false,
+        ],
+    ];
+
+    public static function filesDataProvider(): array
+    {
+        return [
+            '1 file from fileadmin' => [
+                'files' => [
+                    ['file1', 'fileadmin/foo.ext', [], []],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<link href="fileadmin/foo.ext" rel="stylesheet" >',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script src="fileadmin/foo.ext"></script>',
+                    'js_prio' => '',
+                ],
+            ],
+            '1 file from extension' => [
+                'files' => [
+                    ['file1', 'EXT:core/Resource/Public/foo.ext', [], []],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<link href="typo3/sysext/core/Resource/Public/foo.ext" rel="stylesheet" >',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script src="typo3/sysext/core/Resource/Public/foo.ext"></script>',
+                    'js_prio' => '',
+                ],
+            ],
+            '1 file with suspicious source' => [
+                'files' => [
+                    ['file1', '"><script>alert(1)</script><x "', [], []],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<link href="&quot;&gt;&lt;script&gt;alert(1)&lt;/script&gt;&lt;x &quot;" rel="stylesheet" >',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script src="&quot;&gt;&lt;script&gt;alert(1)&lt;/script&gt;&lt;x &quot;"></script>',
+                    'js_prio' => '',
+                ],
+            ],
+            '1 file from external source' => [
+                'files' => [
+                    ['file1', 'https://typo3.org/foo.ext', [], []],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<link href="https://typo3.org/foo.ext" rel="stylesheet" >',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script src="https://typo3.org/foo.ext"></script>',
+                    'js_prio' => '',
+                ],
+            ],
+            '1 file from external source with one parameter' => [
+                'files' => [
+                    ['file1', 'https://typo3.org/foo.ext?foo=bar', [], []],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<link href="https://typo3.org/foo.ext?foo=bar" rel="stylesheet" >',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script src="https://typo3.org/foo.ext?foo=bar"></script>',
+                    'js_prio' => '',
+                ],
+            ],
+            '1 file from external source with two parameters' => [
+                'files' => [
+                    ['file1', 'https://typo3.org/foo.ext?foo=bar&bar=baz', [], []],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<link href="https://typo3.org/foo.ext?foo=bar&amp;bar=baz" rel="stylesheet" >',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script src="https://typo3.org/foo.ext?foo=bar&amp;bar=baz"></script>',
+                    'js_prio' => '',
+                ],
+            ],
+            '2 files' => [
+                'files' => [
+                    ['file1', 'fileadmin/foo.ext', [], []],
+                    ['file2', 'EXT:core/Resource/Public/foo.ext', [], []],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<link href="fileadmin/foo.ext" rel="stylesheet" >' . PHP_EOL . '<link href="typo3/sysext/core/Resource/Public/foo.ext" rel="stylesheet" >',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script src="fileadmin/foo.ext"></script>' . PHP_EOL . '<script src="typo3/sysext/core/Resource/Public/foo.ext"></script>',
+                    'js_prio' => '',
+                ],
+            ],
+            '2 files with override' => [
+                'files' => [
+                    ['file1', 'fileadmin/foo.ext', [], []],
+                    ['file2', 'EXT:core/Resource/Public/foo.ext', [], []],
+                    ['file1', 'EXT:core/Resource/Public/bar.ext', [], []],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<link href="typo3/sysext/core/Resource/Public/bar.ext" rel="stylesheet" >' . PHP_EOL . '<link href="typo3/sysext/core/Resource/Public/foo.ext" rel="stylesheet" >',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script src="typo3/sysext/core/Resource/Public/bar.ext"></script>' . PHP_EOL . '<script src="typo3/sysext/core/Resource/Public/foo.ext"></script>',
+                    'js_prio' => '',
+                ],
+            ],
+            '1 file with attributes' => [
+                'files' => [
+                    ['file1', 'fileadmin/foo.ext', ['rel' => 'foo'], []],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<link rel="foo" href="fileadmin/foo.ext" >',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script rel="foo" src="fileadmin/foo.ext"></script>',
+                    'js_prio' => '',
+                ],
+            ],
+            '1 file with controlled type' => [
+                'files' => [
+                    ['file1', 'fileadmin/foo.ext', ['type' => 'module'], []],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<link type="module" href="fileadmin/foo.ext" rel="stylesheet" >',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script type="module" src="fileadmin/foo.ext"></script>',
+                    'js_prio' => '',
+                ],
+            ],
+            '1 file with attributes override' => [
+                'files' => [
+                    ['file1', 'fileadmin/foo.ext', ['rel' => 'foo', 'another' => 'keep on override'], []],
+                    ['file1', 'fileadmin/foo.ext', ['rel' => 'bar'], []],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<link rel="bar" another="keep on override" href="fileadmin/foo.ext" >',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script rel="bar" another="keep on override" src="fileadmin/foo.ext"></script>',
+                    'js_prio' => '',
+                ],
+            ],
+            '1 file with options' => [
+                'files' => [
+                    ['file1', 'fileadmin/foo.ext', [], ['priority' => true]],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '',
+                    'css_prio' => '<link href="fileadmin/foo.ext" rel="stylesheet" >',
+                    'js_no_prio' => '',
+                    'js_prio' => '<script src="fileadmin/foo.ext"></script>',
+                ],
+            ],
+            '1 file with options override' => [
+                'files' => [
+                    ['file1', 'fileadmin/foo.ext', [], ['priority' => true, 'another' => 'keep on override']],
+                    ['file1', 'fileadmin/foo.ext', [], ['priority' => false]],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<link href="fileadmin/foo.ext" rel="stylesheet" >',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script src="fileadmin/foo.ext"></script>',
+                    'js_prio' => '',
+                ],
+            ],
+        ];
+    }
+
+    #[DataProvider('filesDataProvider')]
+    #[Test]
+    public function styleSheets(array $files, array $expectedMarkup): void
+    {
+        $assetCollector = $this->get(AssetCollector::class);
+        $assetRenderer = $this->get(AssetRenderer::class);
+        foreach ($files as $file) {
+            [$identifier, $source, $attributes, $options] = $file;
+            $assetCollector->addStyleSheet($identifier, $source, $attributes, $options);
+        }
+        self::assertSame($expectedMarkup['css_no_prio'], $assetRenderer->renderStyleSheets());
+        self::assertSame($expectedMarkup['css_prio'], $assetRenderer->renderStyleSheets(true));
+    }
+
+    #[DataProvider('filesDataProvider')]
+    #[Test]
+    public function javaScript(array $files, array $expectedMarkup): void
+    {
+        $assetCollector = $this->get(AssetCollector::class);
+        $assetRenderer = $this->get(AssetRenderer::class);
+        foreach ($files as $file) {
+            [$identifier, $source, $attributes, $options] = $file;
+            $assetCollector->addJavaScript($identifier, $source, $attributes, $options);
+        }
+        self::assertSame($expectedMarkup['js_no_prio'], $assetRenderer->renderJavaScript());
+        self::assertSame($expectedMarkup['js_prio'], $assetRenderer->renderJavaScript(true));
+    }
+
+    public static function inlineDataProvider(): array
+    {
+        return [
+            'simple data' => [
+                'sources' => [
+                    ['identifier_1', 'foo bar baz', [], []],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<style>foo bar baz</style>',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script>foo bar baz</script>',
+                    'js_prio' => '',
+                ],
+            ],
+            '2 times simple data' => [
+                'sources' => [
+                    ['identifier_1', 'foo bar baz', [], []],
+                    ['identifier_2', 'bar baz foo', [], []],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<style>foo bar baz</style>' . PHP_EOL . '<style>bar baz foo</style>',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script>foo bar baz</script>' . PHP_EOL . '<script>bar baz foo</script>',
+                    'js_prio' => '',
+                ],
+            ],
+            '2 times simple data with override' => [
+                'sources' => [
+                    ['identifier_1', 'foo bar baz', [], []],
+                    ['identifier_2', 'bar baz foo', [], []],
+                    ['identifier_1', 'baz foo bar', [], []],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<style>baz foo bar</style>' . PHP_EOL . '<style>bar baz foo</style>',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script>baz foo bar</script>' . PHP_EOL . '<script>bar baz foo</script>',
+                    'js_prio' => '',
+                ],
+            ],
+            'simple data with attributes' => [
+                'sources' => [
+                    ['identifier_1', 'foo bar baz', ['rel' => 'foo'], []],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<style rel="foo">foo bar baz</style>',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script rel="foo">foo bar baz</script>',
+                    'js_prio' => '',
+                ],
+            ],
+            'simple data with attributes override' => [
+                'sources' => [
+                    ['identifier_1', 'foo bar baz', ['rel' => 'foo', 'another' => 'keep on override'], []],
+                    ['identifier_1', 'foo bar baz', ['rel' => 'bar'], []],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<style rel="bar" another="keep on override">foo bar baz</style>',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script rel="bar" another="keep on override">foo bar baz</script>',
+                    'js_prio' => '',
+                ],
+            ],
+            'simple data with options' => [
+                'sources' => [
+                    ['identifier_1', 'foo bar baz', [], ['priority' => true]],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '',
+                    'css_prio' => '<style>foo bar baz</style>',
+                    'js_no_prio' => '',
+                    'js_prio' => '<script>foo bar baz</script>',
+                ],
+            ],
+            'simple data with options override' => [
+                'sources' => [
+                    ['identifier_1', 'foo bar baz', [], ['priority' => true, 'another' => 'keep on override']],
+                    ['identifier_1', 'foo bar baz', [], ['priority' => false]],
+                ],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<style>foo bar baz</style>',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script>foo bar baz</script>',
+                    'js_prio' => '',
+                ],
+            ],
+        ];
+    }
+
+    #[DataProvider('inlineDataProvider')]
+    #[Test]
+    public function inlineJavaScript(array $sources, array $expectedMarkup): void
+    {
+        $assetCollector = $this->get(AssetCollector::class);
+        $assetRenderer = $this->get(AssetRenderer::class);
+        foreach ($sources as $source) {
+            [$identifier, $source, $attributes, $options] = $source;
+            $assetCollector->addInlineJavaScript($identifier, $source, $attributes, $options);
+        }
+        self::assertSame($expectedMarkup['js_no_prio'], $assetRenderer->renderInlineJavaScript());
+        self::assertSame($expectedMarkup['js_prio'], $assetRenderer->renderInlineJavaScript(true));
+    }
+
+    #[DataProvider('inlineDataProvider')]
+    #[Test]
+    public function inlineStyleSheets(array $sources, array $expectedMarkup): void
+    {
+        $assetCollector = $this->get(AssetCollector::class);
+        $assetRenderer = $this->get(AssetRenderer::class);
+        foreach ($sources as $source) {
+            [$identifier, $source, $attributes, $options] = $source;
+            $assetCollector->addInlineStyleSheet($identifier, $source, $attributes, $options);
+        }
+        self::assertSame($expectedMarkup['css_no_prio'], $assetRenderer->renderInlineStyleSheets());
+        self::assertSame($expectedMarkup['css_prio'], $assetRenderer->renderInlineStyleSheets(true));
+    }
+
+    public static function modifyAssetUriEventDataProvider(): array
+    {
+        return [
+            'no priority' => [
+                'source' => 'fileadmin/foo.ext',
+                'options' => ['priority' => false, 'anotherOption' => true],
+                'expectedMarkup' => [
+                    'css_no_prio' => '<link href="fileadmin/foo.ext?someSuffix" rel="stylesheet" >',
+                    'css_prio' => '',
+                    'js_no_prio' => '<script src="fileadmin/foo.ext?someSuffix"></script>',
+                    'js_prio' => '',
+                ],
+            ],
+            'priority' => [
+                'source' => 'fileadmin/foo.ext',
+                'options' => ['priority' => true, 'anotherOption' => true],
+                'expectedMarkup' => [
+                    'css_no_prio' => '',
+                    'css_prio' => '<link href="fileadmin/foo.ext?someSuffix" rel="stylesheet" >',
+                    'js_no_prio' => '',
+                    'js_prio' => '<script src="fileadmin/foo.ext?someSuffix"></script>',
+                ],
+            ],
+        ];
+    }
+}
diff --git a/typo3/sysext/core/Tests/Unit/Page/AssetCollectorTest.php b/typo3/sysext/core/Tests/Unit/Page/AssetCollectorTest.php
index f59bce89a64158a6cbb0a6dd65e180d0f5211f41..b3e6699a966ce59c353b56e11b71d2c32742187e 100644
--- a/typo3/sysext/core/Tests/Unit/Page/AssetCollectorTest.php
+++ b/typo3/sysext/core/Tests/Unit/Page/AssetCollectorTest.php
@@ -17,164 +17,528 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Unit\Page;
 
-use PHPUnit\Framework\Attributes\DataProviderExternal;
+use PHPUnit\Framework\Attributes\DataProvider;
 use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Page\AssetCollector;
 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
 
 final class AssetCollectorTest extends UnitTestCase
 {
-    protected bool $resetSingletonInstances = true;
-    protected ?AssetCollector $assetCollector;
-
-    public function setUp(): void
+    public static function filesDataProvider(): array
     {
-        parent::setUp();
-        $this->assetCollector = new AssetCollector();
+        return [
+            '1 file from fileadmin' => [
+                'files' => [
+                    ['file1', 'fileadmin/foo.ext', [], []],
+                ],
+                'expectedResult' => [
+                    'file1' => [
+                        'source' => 'fileadmin/foo.ext',
+                        'attributes' => [],
+                        'options' => [],
+                    ],
+                ],
+            ],
+            '1 file from extension' => [
+                'files' => [
+                    ['file1', 'EXT:core/Resource/Public/foo.ext', [], []],
+                ],
+                'expectedResult' => [
+                    'file1' => [
+                        'source' => 'EXT:core/Resource/Public/foo.ext',
+                        'attributes' => [],
+                        'options' => [],
+                    ],
+                ],
+            ],
+            '1 file with suspicious source' => [
+                'files' => [
+                    ['file1', '"><script>alert(1)</script><x "', [], []],
+                ],
+                'expectedResult' => [
+                    'file1' => [
+                        'source' => '"><script>alert(1)</script><x "',
+                        'attributes' => [],
+                        'options' => [],
+                    ],
+                ],
+            ],
+            '1 file from external source' => [
+                'files' => [
+                    ['file1', 'https://typo3.org/foo.ext', [], []],
+                ],
+                'expectedResult' => [
+                    'file1' => [
+                        'source' => 'https://typo3.org/foo.ext',
+                        'attributes' => [],
+                        'options' => [],
+                    ],
+                ],
+            ],
+            '1 file from external source with one parameter' => [
+                'files' => [
+                    ['file1', 'https://typo3.org/foo.ext?foo=bar', [], []],
+                ],
+                'expectedResult' => [
+                    'file1' => [
+                        'source' => 'https://typo3.org/foo.ext?foo=bar',
+                        'attributes' => [],
+                        'options' => [],
+                    ],
+                ],
+            ],
+            '1 file from external source with two parameters' => [
+                'files' => [
+                    ['file1', 'https://typo3.org/foo.ext?foo=bar&bar=baz', [], []],
+                ],
+                'expectedResult' => [
+                    'file1' => [
+                        'source' => 'https://typo3.org/foo.ext?foo=bar&bar=baz',
+                        'attributes' => [],
+                        'options' => [],
+                    ],
+                ],
+            ],
+            '2 files' => [
+                'files' => [
+                    ['file1', 'fileadmin/foo.ext', [], []],
+                    ['file2', 'EXT:core/Resource/Public/foo.ext', [], []],
+                ],
+                'expectedResult' => [
+                    'file1' => [
+                        'source' => 'fileadmin/foo.ext',
+                        'attributes' => [],
+                        'options' => [],
+                    ],
+                    'file2' => [
+                        'source' => 'EXT:core/Resource/Public/foo.ext',
+                        'attributes' => [],
+                        'options' => [],
+                    ],
+                ],
+            ],
+            '2 files with override' => [
+                'files' => [
+                    ['file1', 'fileadmin/foo.ext', [], []],
+                    ['file2', 'EXT:core/Resource/Public/foo.ext', [], []],
+                    ['file1', 'EXT:core/Resource/Public/bar.ext', [], []],
+                ],
+                'expectedResult' => [
+                    'file1' => [
+                        'source' => 'EXT:core/Resource/Public/bar.ext',
+                        'attributes' => [],
+                        'options' => [],
+                    ],
+                    'file2' => [
+                        'source' => 'EXT:core/Resource/Public/foo.ext',
+                        'attributes' => [],
+                        'options' => [],
+                    ],
+                ],
+            ],
+            '1 file with attributes' => [
+                'files' => [
+                    ['file1', 'fileadmin/foo.ext', ['rel' => 'foo'], []],
+                ],
+                'expectedResult' => [
+                    'file1' => [
+                        'source' => 'fileadmin/foo.ext',
+                        'attributes' => [
+                            'rel' => 'foo',
+                        ],
+                        'options' => [],
+                    ],
+                ],
+            ],
+            '1 file with controlled type' => [
+                'files' => [
+                    ['file1', 'fileadmin/foo.ext', ['type' => 'module'], []],
+                ],
+                'expectedResult' => [
+                    'file1' => [
+                        'source' => 'fileadmin/foo.ext',
+                        'attributes' => [
+                            'type' => 'module',
+                        ],
+                        'options' => [],
+                    ],
+                ],
+            ],
+            '1 file with attributes override' => [
+                'files' => [
+                    ['file1', 'fileadmin/foo.ext', ['rel' => 'foo', 'another' => 'keep on override'], []],
+                    ['file1', 'fileadmin/foo.ext', ['rel' => 'bar'], []],
+                ],
+                'expectedResult' => [
+                    'file1' => [
+                        'source' => 'fileadmin/foo.ext',
+                        'attributes' => [
+                            'rel' => 'bar',
+                            'another' => 'keep on override',
+                        ],
+                        'options' => [],
+                    ],
+                ],
+            ],
+            '1 file with options' => [
+                'files' => [
+                    ['file1', 'fileadmin/foo.ext', [], ['priority' => true]],
+                ],
+                'expectedResult' => [
+                    'file1' => [
+                        'source' => 'fileadmin/foo.ext',
+                        'attributes' => [],
+                        'options' => [
+                            'priority' => true,
+                        ],
+                    ],
+                ],
+            ],
+            '1 file with options override' => [
+                'files' => [
+                    ['file1', 'fileadmin/foo.ext', [], ['priority' => true, 'another' => 'keep on override']],
+                    ['file1', 'fileadmin/foo.ext', [], ['priority' => false]],
+                ],
+                'expectedResult' => [
+                    'file1' => [
+                        'source' => 'fileadmin/foo.ext',
+                        'attributes' => [],
+                        'options' => [
+                            'priority' => false,
+                            'another' => 'keep on override',
+                        ],
+                    ],
+                ],
+            ],
+        ];
     }
 
-    #[DataProviderExternal(\TYPO3\CMS\Core\Tests\Unit\Page\AssetDataProvider::class, 'filesDataProvider')]
+    #[DataProvider('filesDataProvider')]
     #[Test]
     public function styleSheets(array $files, array $expectedResult): void
     {
+        $assetCollector = new AssetCollector();
         foreach ($files as $file) {
             [$identifier, $source, $attributes, $options] = $file;
-            $this->assetCollector->addStyleSheet($identifier, $source, $attributes, $options);
-            self::assertTrue($this->assetCollector->hasStyleSheet($identifier));
-            self::assertFalse($this->assetCollector->hasInlineStyleSheet($identifier));
-            self::assertFalse($this->assetCollector->hasInlineJavaScript($identifier));
-            self::assertFalse($this->assetCollector->hasJavaScript($identifier));
-            self::assertFalse($this->assetCollector->hasMedia($identifier));
+            $assetCollector->addStyleSheet($identifier, $source, $attributes, $options);
+            self::assertTrue($assetCollector->hasStyleSheet($identifier));
+            self::assertFalse($assetCollector->hasInlineStyleSheet($identifier));
+            self::assertFalse($assetCollector->hasInlineJavaScript($identifier));
+            self::assertFalse($assetCollector->hasJavaScript($identifier));
+            self::assertFalse($assetCollector->hasMedia($identifier));
         }
-        self::assertSame($expectedResult, $this->assetCollector->getStyleSheets());
-        self::assertSame([], $this->assetCollector->getInlineStyleSheets());
-        self::assertSame([], $this->assetCollector->getInlineJavaScripts());
-        self::assertSame([], $this->assetCollector->getJavaScripts());
-        self::assertSame([], $this->assetCollector->getMedia());
+        self::assertSame($expectedResult, $assetCollector->getStyleSheets());
+        self::assertSame([], $assetCollector->getInlineStyleSheets());
+        self::assertSame([], $assetCollector->getInlineJavaScripts());
+        self::assertSame([], $assetCollector->getJavaScripts());
+        self::assertSame([], $assetCollector->getMedia());
         foreach ($files as $file) {
             [$identifier] = $file;
-            $this->assetCollector->removeStyleSheet($identifier);
+            $assetCollector->removeStyleSheet($identifier);
         }
-        self::assertSame([], $this->assetCollector->getStyleSheets());
-        self::assertSame([], $this->assetCollector->getInlineStyleSheets());
-        self::assertSame([], $this->assetCollector->getInlineJavaScripts());
-        self::assertSame([], $this->assetCollector->getJavaScripts());
-        self::assertSame([], $this->assetCollector->getMedia());
+        self::assertSame([], $assetCollector->getStyleSheets());
+        self::assertSame([], $assetCollector->getInlineStyleSheets());
+        self::assertSame([], $assetCollector->getInlineJavaScripts());
+        self::assertSame([], $assetCollector->getJavaScripts());
+        self::assertSame([], $assetCollector->getMedia());
     }
 
-    #[DataProviderExternal(\TYPO3\CMS\Core\Tests\Unit\Page\AssetDataProvider::class, 'filesDataProvider')]
+    #[DataProvider('filesDataProvider')]
     #[Test]
     public function javaScript(array $files, array $expectedResult): void
     {
+        $assetCollector = new AssetCollector();
         foreach ($files as $file) {
             [$identifier, $source, $attributes, $options] = $file;
-            $this->assetCollector->addJavaScript($identifier, $source, $attributes, $options);
-            self::assertTrue($this->assetCollector->hasJavaScript($identifier));
-            self::assertFalse($this->assetCollector->hasInlineStyleSheet($identifier));
-            self::assertFalse($this->assetCollector->hasInlineJavaScript($identifier));
-            self::assertFalse($this->assetCollector->hasStyleSheet($identifier));
-            self::assertFalse($this->assetCollector->hasMedia($identifier));
+            $assetCollector->addJavaScript($identifier, $source, $attributes, $options);
+            self::assertTrue($assetCollector->hasJavaScript($identifier));
+            self::assertFalse($assetCollector->hasInlineStyleSheet($identifier));
+            self::assertFalse($assetCollector->hasInlineJavaScript($identifier));
+            self::assertFalse($assetCollector->hasStyleSheet($identifier));
+            self::assertFalse($assetCollector->hasMedia($identifier));
         }
-        self::assertSame($expectedResult, $this->assetCollector->getJavaScripts());
-        self::assertSame([], $this->assetCollector->getInlineStyleSheets());
-        self::assertSame([], $this->assetCollector->getInlineJavaScripts());
-        self::assertSame([], $this->assetCollector->getStyleSheets());
-        self::assertSame([], $this->assetCollector->getMedia());
+        self::assertSame($expectedResult, $assetCollector->getJavaScripts());
+        self::assertSame([], $assetCollector->getInlineStyleSheets());
+        self::assertSame([], $assetCollector->getInlineJavaScripts());
+        self::assertSame([], $assetCollector->getStyleSheets());
+        self::assertSame([], $assetCollector->getMedia());
         foreach ($files as $file) {
             [$identifier] = $file;
-            $this->assetCollector->removeJavaScript($identifier);
+            $assetCollector->removeJavaScript($identifier);
         }
-        self::assertSame([], $this->assetCollector->getJavaScripts());
-        self::assertSame([], $this->assetCollector->getInlineStyleSheets());
-        self::assertSame([], $this->assetCollector->getInlineJavaScripts());
-        self::assertSame([], $this->assetCollector->getStyleSheets());
-        self::assertSame([], $this->assetCollector->getMedia());
+        self::assertSame([], $assetCollector->getJavaScripts());
+        self::assertSame([], $assetCollector->getInlineStyleSheets());
+        self::assertSame([], $assetCollector->getInlineJavaScripts());
+        self::assertSame([], $assetCollector->getStyleSheets());
+        self::assertSame([], $assetCollector->getMedia());
+    }
+
+    public static function inlineDataProvider(): array
+    {
+        return [
+            'simple data' => [
+                'sources' => [
+                    ['identifier_1', 'foo bar baz', [], []],
+                ],
+                'expectedResult' => [
+                    'identifier_1' => [
+                        'source' => 'foo bar baz',
+                        'attributes' => [],
+                        'options' => [],
+                    ],
+                ],
+            ],
+            '2 times simple data' => [
+                'sources' => [
+                    ['identifier_1', 'foo bar baz', [], []],
+                    ['identifier_2', 'bar baz foo', [], []],
+                ],
+                'expectedResult' => [
+                    'identifier_1' => [
+                        'source' => 'foo bar baz',
+                        'attributes' => [],
+                        'options' => [],
+                    ],
+                    'identifier_2' => [
+                        'source' => 'bar baz foo',
+                        'attributes' => [],
+                        'options' => [],
+                    ],
+                ],
+            ],
+            '2 times simple data with override' => [
+                'sources' => [
+                    ['identifier_1', 'foo bar baz', [], []],
+                    ['identifier_2', 'bar baz foo', [], []],
+                    ['identifier_1', 'baz foo bar', [], []],
+                ],
+                'expectedResult' => [
+                    'identifier_1' => [
+                        'source' => 'baz foo bar',
+                        'attributes' => [],
+                        'options' => [],
+                    ],
+                    'identifier_2' => [
+                        'source' => 'bar baz foo',
+                        'attributes' => [],
+                        'options' => [],
+                    ],
+                ],
+            ],
+            'simple data with attributes' => [
+                'sources' => [
+                    ['identifier_1', 'foo bar baz', ['rel' => 'foo'], []],
+                ],
+                'expectedResult' => [
+                    'identifier_1' => [
+                        'source' => 'foo bar baz',
+                        'attributes' => [
+                            'rel' => 'foo',
+                        ],
+                        'options' => [],
+                    ],
+                ],
+            ],
+            'simple data with attributes override' => [
+                'sources' => [
+                    ['identifier_1', 'foo bar baz', ['rel' => 'foo', 'another' => 'keep on override'], []],
+                    ['identifier_1', 'foo bar baz', ['rel' => 'bar'], []],
+                ],
+                'expectedResult' => [
+                    'identifier_1' => [
+                        'source' => 'foo bar baz',
+                        'attributes' => [
+                            'rel' => 'bar',
+                            'another' => 'keep on override',
+                        ],
+                        'options' => [],
+                    ],
+                ],
+            ],
+            'simple data with options' => [
+                'sources' => [
+                    ['identifier_1', 'foo bar baz', [], ['priority' => true]],
+                ],
+                'expectedResult' => [
+                    'identifier_1' => [
+                        'source' => 'foo bar baz',
+                        'attributes' => [],
+                        'options' => [
+                            'priority' => true,
+                        ],
+                    ],
+                ],
+            ],
+            'simple data with options override' => [
+                'sources' => [
+                    ['identifier_1', 'foo bar baz', [], ['priority' => true, 'another' => 'keep on override']],
+                    ['identifier_1', 'foo bar baz', [], ['priority' => false]],
+                ],
+                'expectedResult' => [
+                    'identifier_1' => [
+                        'source' => 'foo bar baz',
+                        'attributes' => [],
+                        'options' => [
+                            'priority' => false,
+                            'another' => 'keep on override',
+                        ],
+                    ],
+                ],
+            ],
+        ];
     }
 
-    #[DataProviderExternal(\TYPO3\CMS\Core\Tests\Unit\Page\AssetDataProvider::class, 'inlineDataProvider')]
+    #[DataProvider('inlineDataProvider')]
     #[Test]
     public function inlineJavaScript(array $sources, array $expectedResult): void
     {
+        $assetCollector = new AssetCollector();
         foreach ($sources as $source) {
             [$identifier, $source, $attributes, $options] = $source;
-            $this->assetCollector->addInlineJavaScript($identifier, $source, $attributes, $options);
-            self::assertTrue($this->assetCollector->hasInlineJavaScript($identifier));
-            self::assertFalse($this->assetCollector->hasInlineStyleSheet($identifier));
-            self::assertFalse($this->assetCollector->hasJavaScript($identifier));
-            self::assertFalse($this->assetCollector->hasStyleSheet($identifier));
-            self::assertFalse($this->assetCollector->hasMedia($identifier));
+            $assetCollector->addInlineJavaScript($identifier, $source, $attributes, $options);
+            self::assertTrue($assetCollector->hasInlineJavaScript($identifier));
+            self::assertFalse($assetCollector->hasInlineStyleSheet($identifier));
+            self::assertFalse($assetCollector->hasJavaScript($identifier));
+            self::assertFalse($assetCollector->hasStyleSheet($identifier));
+            self::assertFalse($assetCollector->hasMedia($identifier));
         }
-        self::assertSame($expectedResult, $this->assetCollector->getInlineJavaScripts());
-        self::assertSame([], $this->assetCollector->getInlineStyleSheets());
-        self::assertSame([], $this->assetCollector->getJavaScripts());
-        self::assertSame([], $this->assetCollector->getStyleSheets());
-        self::assertSame([], $this->assetCollector->getMedia());
+        self::assertSame($expectedResult, $assetCollector->getInlineJavaScripts());
+        self::assertSame([], $assetCollector->getInlineStyleSheets());
+        self::assertSame([], $assetCollector->getJavaScripts());
+        self::assertSame([], $assetCollector->getStyleSheets());
+        self::assertSame([], $assetCollector->getMedia());
         foreach ($sources as $source) {
             [$identifier] = $source;
-            $this->assetCollector->removeInlineJavaScript($identifier);
+            $assetCollector->removeInlineJavaScript($identifier);
         }
-        self::assertSame([], $this->assetCollector->getInlineJavaScripts());
-        self::assertSame([], $this->assetCollector->getInlineStyleSheets());
-        self::assertSame([], $this->assetCollector->getJavaScripts());
-        self::assertSame([], $this->assetCollector->getStyleSheets());
-        self::assertSame([], $this->assetCollector->getMedia());
+        self::assertSame([], $assetCollector->getInlineJavaScripts());
+        self::assertSame([], $assetCollector->getInlineStyleSheets());
+        self::assertSame([], $assetCollector->getJavaScripts());
+        self::assertSame([], $assetCollector->getStyleSheets());
+        self::assertSame([], $assetCollector->getMedia());
     }
 
-    #[DataProviderExternal(\TYPO3\CMS\Core\Tests\Unit\Page\AssetDataProvider::class, 'inlineDataProvider')]
+    #[DataProvider('inlineDataProvider')]
     #[Test]
     public function inlineStyles(array $sources, array $expectedResult): void
     {
+        $assetCollector = new AssetCollector();
         foreach ($sources as $source) {
             [$identifier, $source, $attributes, $options] = $source;
-            $this->assetCollector->addInlineStyleSheet($identifier, $source, $attributes, $options);
-            self::assertTrue($this->assetCollector->hasInlineStyleSheet($identifier));
-            self::assertFalse($this->assetCollector->hasInlineJavaScript($identifier));
-            self::assertFalse($this->assetCollector->hasJavaScript($identifier));
-            self::assertFalse($this->assetCollector->hasStyleSheet($identifier));
-            self::assertFalse($this->assetCollector->hasMedia($identifier));
+            $assetCollector->addInlineStyleSheet($identifier, $source, $attributes, $options);
+            self::assertTrue($assetCollector->hasInlineStyleSheet($identifier));
+            self::assertFalse($assetCollector->hasInlineJavaScript($identifier));
+            self::assertFalse($assetCollector->hasJavaScript($identifier));
+            self::assertFalse($assetCollector->hasStyleSheet($identifier));
+            self::assertFalse($assetCollector->hasMedia($identifier));
         }
-        self::assertSame($expectedResult, $this->assetCollector->getInlineStyleSheets());
-        self::assertSame([], $this->assetCollector->getInlineJavaScripts());
-        self::assertSame([], $this->assetCollector->getJavaScripts());
-        self::assertSame([], $this->assetCollector->getStyleSheets());
-        self::assertSame([], $this->assetCollector->getMedia());
+        self::assertSame($expectedResult, $assetCollector->getInlineStyleSheets());
+        self::assertSame([], $assetCollector->getInlineJavaScripts());
+        self::assertSame([], $assetCollector->getJavaScripts());
+        self::assertSame([], $assetCollector->getStyleSheets());
+        self::assertSame([], $assetCollector->getMedia());
         foreach ($sources as $source) {
             [$identifier] = $source;
-            $this->assetCollector->removeInlineStyleSheet($identifier);
+            $assetCollector->removeInlineStyleSheet($identifier);
         }
-        self::assertSame([], $this->assetCollector->getInlineStyleSheets());
-        self::assertSame([], $this->assetCollector->getInlineJavaScripts());
-        self::assertSame([], $this->assetCollector->getJavaScripts());
-        self::assertSame([], $this->assetCollector->getStyleSheets());
-        self::assertSame([], $this->assetCollector->getMedia());
+        self::assertSame([], $assetCollector->getInlineStyleSheets());
+        self::assertSame([], $assetCollector->getInlineJavaScripts());
+        self::assertSame([], $assetCollector->getJavaScripts());
+        self::assertSame([], $assetCollector->getStyleSheets());
+        self::assertSame([], $assetCollector->getMedia());
+    }
+
+    public static function mediaDataProvider(): array
+    {
+        return [
+            '1 image no additional information' => [
+                'images' => [
+                    ['fileadmin/foo.png', []],
+                ],
+                'expectedResult' => [
+                    'fileadmin/foo.png' => [],
+                ],
+            ],
+            '2 images no additional information' => [
+                'images' => [
+                    ['fileadmin/foo.png', []],
+                    ['fileadmin/bar.png', []],
+                ],
+                'expectedResult' => [
+                    'fileadmin/foo.png' => [],
+                    'fileadmin/bar.png' => [],
+                ],
+            ],
+            '1 image with additional information' => [
+                'images' => [
+                    ['fileadmin/foo.png', ['foo' => 'bar']],
+                ],
+                'expectedResult' => [
+                    'fileadmin/foo.png' => ['foo' => 'bar'],
+                ],
+            ],
+            '2 images with additional information' => [
+                'images' => [
+                    ['fileadmin/foo.png', ['foo' => 'bar']],
+                    ['fileadmin/bar.png', ['foo' => 'baz']],
+                ],
+                'expectedResult' => [
+                    'fileadmin/foo.png' => ['foo' => 'bar'],
+                    'fileadmin/bar.png' => ['foo' => 'baz'],
+                ],
+            ],
+            '2 images with additional information override' => [
+                'images' => [
+                    ['fileadmin/foo.png', ['foo' => 'bar']],
+                    ['fileadmin/bar.png', ['foo' => 'baz']],
+                    ['fileadmin/foo.png', ['foo' => 'baz']],
+                ],
+                'expectedResult' => [
+                    'fileadmin/foo.png' => ['foo' => 'baz'],
+                    'fileadmin/bar.png' => ['foo' => 'baz'],
+                ],
+            ],
+            '2 images with additional information override keep existing' => [
+                'images' => [
+                    ['fileadmin/foo.png', ['foo' => 'bar', 'bar' => 'baz']],
+                    ['fileadmin/bar.png', ['foo' => 'baz']],
+                    ['fileadmin/foo.png', ['foo' => 'baz']],
+                ],
+                'expectedResult' => [
+                    'fileadmin/foo.png' => ['foo' => 'baz', 'bar' => 'baz'],
+                    'fileadmin/bar.png' => ['foo' => 'baz'],
+                ],
+            ],
+        ];
     }
 
-    #[DataProviderExternal(\TYPO3\CMS\Core\Tests\Unit\Page\AssetDataProvider::class, 'mediaDataProvider')]
+    #[DataProvider('mediaDataProvider')]
     #[Test]
     public function media(array $images, array $expectedResult): void
     {
+        $assetCollector = new AssetCollector();
         foreach ($images as $image) {
             [$fileName, $additionalInformation] = $image;
-            $this->assetCollector->addMedia($fileName, $additionalInformation);
-            self::assertTrue($this->assetCollector->hasMedia($fileName));
-            self::assertFalse($this->assetCollector->hasInlineStyleSheet($fileName));
-            self::assertFalse($this->assetCollector->hasInlineJavaScript($fileName));
-            self::assertFalse($this->assetCollector->hasJavaScript($fileName));
-            self::assertFalse($this->assetCollector->hasStyleSheet($fileName));
+            $assetCollector->addMedia($fileName, $additionalInformation);
+            self::assertTrue($assetCollector->hasMedia($fileName));
+            self::assertFalse($assetCollector->hasInlineStyleSheet($fileName));
+            self::assertFalse($assetCollector->hasInlineJavaScript($fileName));
+            self::assertFalse($assetCollector->hasJavaScript($fileName));
+            self::assertFalse($assetCollector->hasStyleSheet($fileName));
         }
-        self::assertSame($expectedResult, $this->assetCollector->getMedia());
-        self::assertSame([], $this->assetCollector->getInlineStyleSheets());
-        self::assertSame([], $this->assetCollector->getInlineJavaScripts());
-        self::assertSame([], $this->assetCollector->getJavaScripts());
-        self::assertSame([], $this->assetCollector->getStyleSheets());
+        self::assertSame($expectedResult, $assetCollector->getMedia());
+        self::assertSame([], $assetCollector->getInlineStyleSheets());
+        self::assertSame([], $assetCollector->getInlineJavaScripts());
+        self::assertSame([], $assetCollector->getJavaScripts());
+        self::assertSame([], $assetCollector->getStyleSheets());
         foreach ($images as $image) {
             [$fileName] = $image;
-            $this->assetCollector->removeMedia($fileName);
+            $assetCollector->removeMedia($fileName);
         }
-        self::assertSame([], $this->assetCollector->getMedia());
-        self::assertSame([], $this->assetCollector->getInlineStyleSheets());
-        self::assertSame([], $this->assetCollector->getInlineJavaScripts());
-        self::assertSame([], $this->assetCollector->getJavaScripts());
-        self::assertSame([], $this->assetCollector->getStyleSheets());
+        self::assertSame([], $assetCollector->getMedia());
+        self::assertSame([], $assetCollector->getInlineStyleSheets());
+        self::assertSame([], $assetCollector->getInlineJavaScripts());
+        self::assertSame([], $assetCollector->getJavaScripts());
+        self::assertSame([], $assetCollector->getStyleSheets());
     }
 }
diff --git a/typo3/sysext/core/Tests/Unit/Page/AssetDataProvider.php b/typo3/sysext/core/Tests/Unit/Page/AssetDataProvider.php
deleted file mode 100644
index cf9568411a4eb042ce9f4dc5e1d9faca61cc81b2..0000000000000000000000000000000000000000
--- a/typo3/sysext/core/Tests/Unit/Page/AssetDataProvider.php
+++ /dev/null
@@ -1,530 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-namespace TYPO3\CMS\Core\Tests\Unit\Page;
-
-use TYPO3\CMS\Core\Page\Event\BeforeJavaScriptsRenderingEvent;
-use TYPO3\CMS\Core\Page\Event\BeforeStylesheetsRenderingEvent;
-
-class AssetDataProvider
-{
-    public static function filesDataProvider(): array
-    {
-        return [
-            '1 file from fileadmin' => [
-                [
-                    ['file1', 'fileadmin/foo.ext', [], []],
-                ],
-                [
-                    'file1' => [
-                        'source' => 'fileadmin/foo.ext',
-                        'attributes' => [],
-                        'options' => [],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<link href="fileadmin/foo.ext" rel="stylesheet" >',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script src="fileadmin/foo.ext"></script>',
-                    'js_prio' => '',
-                ],
-            ],
-            '1 file from extension' => [
-                [
-                    ['file1', 'EXT:core/Resource/Public/foo.ext', [], []],
-                ],
-                [
-                    'file1' => [
-                        'source' => 'EXT:core/Resource/Public/foo.ext',
-                        'attributes' => [],
-                        'options' => [],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<link href="typo3/sysext/core/Resource/Public/foo.ext" rel="stylesheet" >',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script src="typo3/sysext/core/Resource/Public/foo.ext"></script>',
-                    'js_prio' => '',
-                ],
-            ],
-            '1 file with suspicious source' => [
-                [
-                    ['file1', '"><script>alert(1)</script><x "', [], []],
-                ],
-                [
-                    'file1' => [
-                        'source' => '"><script>alert(1)</script><x "',
-                        'attributes' => [],
-                        'options' => [],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<link href="&quot;&gt;&lt;script&gt;alert(1)&lt;/script&gt;&lt;x &quot;" rel="stylesheet" >',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script src="&quot;&gt;&lt;script&gt;alert(1)&lt;/script&gt;&lt;x &quot;"></script>',
-                    'js_prio' => '',
-                ],
-            ],
-            '1 file from external source' => [
-                [
-                    ['file1', 'https://typo3.org/foo.ext', [], []],
-                ],
-                [
-                    'file1' => [
-                        'source' => 'https://typo3.org/foo.ext',
-                        'attributes' => [],
-                        'options' => [],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<link href="https://typo3.org/foo.ext" rel="stylesheet" >',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script src="https://typo3.org/foo.ext"></script>',
-                    'js_prio' => '',
-                ],
-            ],
-            '1 file from external source with one parameter' => [
-                [
-                    ['file1', 'https://typo3.org/foo.ext?foo=bar', [], []],
-                ],
-                [
-                    'file1' => [
-                        'source' => 'https://typo3.org/foo.ext?foo=bar',
-                        'attributes' => [],
-                        'options' => [],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<link href="https://typo3.org/foo.ext?foo=bar" rel="stylesheet" >',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script src="https://typo3.org/foo.ext?foo=bar"></script>',
-                    'js_prio' => '',
-                ],
-            ],
-            '1 file from external source with two parameters' => [
-                [
-                    ['file1', 'https://typo3.org/foo.ext?foo=bar&bar=baz', [], []],
-                ],
-                [
-                    'file1' => [
-                        'source' => 'https://typo3.org/foo.ext?foo=bar&bar=baz',
-                        'attributes' => [],
-                        'options' => [],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<link href="https://typo3.org/foo.ext?foo=bar&amp;bar=baz" rel="stylesheet" >',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script src="https://typo3.org/foo.ext?foo=bar&amp;bar=baz"></script>',
-                    'js_prio' => '',
-                ],
-            ],
-            '2 files' => [
-                [
-                    ['file1', 'fileadmin/foo.ext', [], []],
-                    ['file2', 'EXT:core/Resource/Public/foo.ext', [], []],
-                ],
-                [
-                    'file1' => [
-                        'source' => 'fileadmin/foo.ext',
-                        'attributes' => [],
-                        'options' => [],
-                    ],
-                    'file2' => [
-                        'source' => 'EXT:core/Resource/Public/foo.ext',
-                        'attributes' => [],
-                        'options' => [],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<link href="fileadmin/foo.ext" rel="stylesheet" >' . LF . '<link href="typo3/sysext/core/Resource/Public/foo.ext" rel="stylesheet" >',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script src="fileadmin/foo.ext"></script>' . LF . '<script src="typo3/sysext/core/Resource/Public/foo.ext"></script>',
-                    'js_prio' => '',
-                ],
-            ],
-            '2 files with override' => [
-                [
-                    ['file1', 'fileadmin/foo.ext', [], []],
-                    ['file2', 'EXT:core/Resource/Public/foo.ext', [], []],
-                    ['file1', 'EXT:core/Resource/Public/bar.ext', [], []],
-                ],
-                [
-                    'file1' => [
-                        'source' => 'EXT:core/Resource/Public/bar.ext',
-                        'attributes' => [],
-                        'options' => [],
-                    ],
-                    'file2' => [
-                        'source' => 'EXT:core/Resource/Public/foo.ext',
-                        'attributes' => [],
-                        'options' => [],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<link href="typo3/sysext/core/Resource/Public/bar.ext" rel="stylesheet" >' . LF . '<link href="typo3/sysext/core/Resource/Public/foo.ext" rel="stylesheet" >',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script src="typo3/sysext/core/Resource/Public/bar.ext"></script>' . LF . '<script src="typo3/sysext/core/Resource/Public/foo.ext"></script>',
-                    'js_prio' => '',
-                ],
-            ],
-            '1 file with attributes' => [
-                [
-                    ['file1', 'fileadmin/foo.ext', ['rel' => 'foo'], []],
-                ],
-                [
-                    'file1' => [
-                        'source' => 'fileadmin/foo.ext',
-                        'attributes' => [
-                            'rel' => 'foo',
-                        ],
-                        'options' => [],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<link rel="foo" href="fileadmin/foo.ext" >',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script rel="foo" src="fileadmin/foo.ext"></script>',
-                    'js_prio' => '',
-                ],
-            ],
-            '1 file with controlled type' => [
-                [
-                    ['file1', 'fileadmin/foo.ext', ['type' => 'module'], []],
-                ],
-                [
-                    'file1' => [
-                        'source' => 'fileadmin/foo.ext',
-                        'attributes' => [
-                            'type' => 'module',
-                        ],
-                        'options' => [],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<link type="module" href="fileadmin/foo.ext" rel="stylesheet" >',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script type="module" src="fileadmin/foo.ext"></script>',
-                    'js_prio' => '',
-                ],
-            ],
-            '1 file with attributes override' => [
-                [
-                    ['file1', 'fileadmin/foo.ext', ['rel' => 'foo', 'another' => 'keep on override'], []],
-                    ['file1', 'fileadmin/foo.ext', ['rel' => 'bar'], []],
-                ],
-                [
-                    'file1' => [
-                        'source' => 'fileadmin/foo.ext',
-                        'attributes' => [
-                            'rel' => 'bar',
-                            'another' => 'keep on override',
-                        ],
-                        'options' => [],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<link rel="bar" another="keep on override" href="fileadmin/foo.ext" >',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script rel="bar" another="keep on override" src="fileadmin/foo.ext"></script>',
-                    'js_prio' => '',
-                ],
-            ],
-            '1 file with options' => [
-                [
-                    ['file1', 'fileadmin/foo.ext', [], ['priority' => true]],
-                ],
-                [
-                    'file1' => [
-                        'source' => 'fileadmin/foo.ext',
-                        'attributes' => [],
-                        'options' => [
-                            'priority' => true,
-                        ],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '',
-                    'css_prio' => '<link href="fileadmin/foo.ext" rel="stylesheet" >',
-                    'js_no_prio' => '',
-                    'js_prio' => '<script src="fileadmin/foo.ext"></script>',
-                ],
-            ],
-            '1 file with options override' => [
-                [
-                    ['file1', 'fileadmin/foo.ext', [], ['priority' => true, 'another' => 'keep on override']],
-                    ['file1', 'fileadmin/foo.ext', [], ['priority' => false]],
-                ],
-                [
-                    'file1' => [
-                        'source' => 'fileadmin/foo.ext',
-                        'attributes' => [],
-                        'options' => [
-                            'priority' => false,
-                            'another' => 'keep on override',
-                        ],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<link href="fileadmin/foo.ext" rel="stylesheet" >',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script src="fileadmin/foo.ext"></script>',
-                    'js_prio' => '',
-                ],
-            ],
-        ];
-    }
-
-    public static function inlineDataProvider(): array
-    {
-        return [
-            'simple data' => [
-                [
-                    ['identifier_1', 'foo bar baz', [], []],
-                ],
-                [
-                    'identifier_1' => [
-                        'source' => 'foo bar baz',
-                        'attributes' => [],
-                        'options' => [],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<style>foo bar baz</style>',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script>foo bar baz</script>',
-                    'js_prio' => '',
-                ],
-            ],
-            '2 times simple data' => [
-                [
-                    ['identifier_1', 'foo bar baz', [], []],
-                    ['identifier_2', 'bar baz foo', [], []],
-                ],
-                [
-                    'identifier_1' => [
-                        'source' => 'foo bar baz',
-                        'attributes' => [],
-                        'options' => [],
-                    ],
-                    'identifier_2' => [
-                        'source' => 'bar baz foo',
-                        'attributes' => [],
-                        'options' => [],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<style>foo bar baz</style>' . LF . '<style>bar baz foo</style>',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script>foo bar baz</script>' . LF . '<script>bar baz foo</script>',
-                    'js_prio' => '',
-                ],
-            ],
-            '2 times simple data with override' => [
-                [
-                    ['identifier_1', 'foo bar baz', [], []],
-                    ['identifier_2', 'bar baz foo', [], []],
-                    ['identifier_1', 'baz foo bar', [], []],
-                ],
-                [
-                    'identifier_1' => [
-                        'source' => 'baz foo bar',
-                        'attributes' => [],
-                        'options' => [],
-                    ],
-                    'identifier_2' => [
-                        'source' => 'bar baz foo',
-                        'attributes' => [],
-                        'options' => [],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<style>baz foo bar</style>' . LF . '<style>bar baz foo</style>',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script>baz foo bar</script>' . LF . '<script>bar baz foo</script>',
-                    'js_prio' => '',
-                ],
-            ],
-            'simple data with attributes' => [
-                [
-                    ['identifier_1', 'foo bar baz', ['rel' => 'foo'], []],
-                ],
-                [
-                    'identifier_1' => [
-                        'source' => 'foo bar baz',
-                        'attributes' => [
-                            'rel' => 'foo',
-                        ],
-                        'options' => [],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<style rel="foo">foo bar baz</style>',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script rel="foo">foo bar baz</script>',
-                    'js_prio' => '',
-                ],
-            ],
-            'simple data with attributes override' => [
-                [
-                    ['identifier_1', 'foo bar baz', ['rel' => 'foo', 'another' => 'keep on override'], []],
-                    ['identifier_1', 'foo bar baz', ['rel' => 'bar'], []],
-                ],
-                [
-                    'identifier_1' => [
-                        'source' => 'foo bar baz',
-                        'attributes' => [
-                            'rel' => 'bar',
-                            'another' => 'keep on override',
-                        ],
-                        'options' => [],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<style rel="bar" another="keep on override">foo bar baz</style>',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script rel="bar" another="keep on override">foo bar baz</script>',
-                    'js_prio' => '',
-                ],
-            ],
-            'simple data with options' => [
-                [
-                    ['identifier_1', 'foo bar baz', [], ['priority' => true]],
-                ],
-                [
-                    'identifier_1' => [
-                        'source' => 'foo bar baz',
-                        'attributes' => [],
-                        'options' => [
-                            'priority' => true,
-                        ],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '',
-                    'css_prio' => '<style>foo bar baz</style>',
-                    'js_no_prio' => '',
-                    'js_prio' => '<script>foo bar baz</script>',
-                ],
-            ],
-            'simple data with options override' => [
-                [
-                    ['identifier_1', 'foo bar baz', [], ['priority' => true, 'another' => 'keep on override']],
-                    ['identifier_1', 'foo bar baz', [], ['priority' => false]],
-                ],
-                [
-                    'identifier_1' => [
-                        'source' => 'foo bar baz',
-                        'attributes' => [],
-                        'options' => [
-                            'priority' => false,
-                            'another' => 'keep on override',
-                        ],
-                    ],
-                ],
-                [
-                    'css_no_prio' => '<style>foo bar baz</style>',
-                    'css_prio' => '',
-                    'js_no_prio' => '<script>foo bar baz</script>',
-                    'js_prio' => '',
-                ],
-            ],
-        ];
-    }
-
-    public static function mediaDataProvider(): array
-    {
-        return [
-            '1 image no additional information' => [
-                [
-                    ['fileadmin/foo.png', []],
-                ],
-                [
-                    'fileadmin/foo.png' => [],
-                ],
-            ],
-            '2 images no additional information' => [
-                [
-                    ['fileadmin/foo.png', []],
-                    ['fileadmin/bar.png', []],
-                ],
-                [
-                    'fileadmin/foo.png' => [],
-                    'fileadmin/bar.png' => [],
-                ],
-            ],
-            '1 image with additional information' => [
-                [
-                    ['fileadmin/foo.png', ['foo' => 'bar']],
-                ],
-                [
-                    'fileadmin/foo.png' => ['foo' => 'bar'],
-                ],
-            ],
-            '2 images with additional information' => [
-                [
-                    ['fileadmin/foo.png', ['foo' => 'bar']],
-                    ['fileadmin/bar.png', ['foo' => 'baz']],
-                ],
-                [
-                    'fileadmin/foo.png' => ['foo' => 'bar'],
-                    'fileadmin/bar.png' => ['foo' => 'baz'],
-                ],
-            ],
-            '2 images with additional information override' => [
-                [
-                    ['fileadmin/foo.png', ['foo' => 'bar']],
-                    ['fileadmin/bar.png', ['foo' => 'baz']],
-                    ['fileadmin/foo.png', ['foo' => 'baz']],
-                ],
-                [
-                    'fileadmin/foo.png' => ['foo' => 'baz'],
-                    'fileadmin/bar.png' => ['foo' => 'baz'],
-                ],
-            ],
-            '2 images with additional information override keep existing' => [
-                [
-                    ['fileadmin/foo.png', ['foo' => 'bar', 'bar' => 'baz']],
-                    ['fileadmin/bar.png', ['foo' => 'baz']],
-                    ['fileadmin/foo.png', ['foo' => 'baz']],
-                ],
-                [
-                    'fileadmin/foo.png' => ['foo' => 'baz', 'bar' => 'baz'],
-                    'fileadmin/bar.png' => ['foo' => 'baz'],
-                ],
-            ],
-        ];
-    }
-
-    /**
-     * cross-product of all combinations of AssetRenderer::render*() methods and priorities
-     * @return array[] [render method name, isInline, isPriority, event class]
-     */
-    public static function renderMethodsAndEventsDataProvider(): array
-    {
-        return [
-            ['renderInlineJavaScript', true, true, BeforeJavaScriptsRenderingEvent::class],
-            ['renderInlineJavaScript', true, false, BeforeJavaScriptsRenderingEvent::class],
-            ['renderJavaScript', false, true, BeforeJavaScriptsRenderingEvent::class],
-            ['renderJavaScript', false, false, BeforeJavaScriptsRenderingEvent::class],
-            ['renderInlineStylesheets', true, true, BeforeStylesheetsRenderingEvent::class],
-            ['renderInlineStylesheets', true, false, BeforeStylesheetsRenderingEvent::class],
-            ['renderStylesheets', false, true, BeforeStylesheetsRenderingEvent::class],
-            ['renderStylesheets', false, false, BeforeStylesheetsRenderingEvent::class],
-        ];
-    }
-}
diff --git a/typo3/sysext/core/Tests/Unit/Page/AssetRendererTest.php b/typo3/sysext/core/Tests/Unit/Page/AssetRendererTest.php
index c442712585fdc9cdf74a8147ad285927576cf7e6..9f61bfe03b16143884a57ef0b16020cd452b4962 100644
--- a/typo3/sysext/core/Tests/Unit/Page/AssetRendererTest.php
+++ b/typo3/sysext/core/Tests/Unit/Page/AssetRendererTest.php
@@ -17,82 +17,36 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Unit\Page;
 
-use PHPUnit\Framework\Attributes\DataProviderExternal;
+use PHPUnit\Framework\Attributes\DataProvider;
 use PHPUnit\Framework\Attributes\Test;
-use PHPUnit\Framework\MockObject\MockObject;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use TYPO3\CMS\Core\Page\AssetCollector;
 use TYPO3\CMS\Core\Page\AssetRenderer;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Page\Event\BeforeJavaScriptsRenderingEvent;
+use TYPO3\CMS\Core\Page\Event\BeforeStylesheetsRenderingEvent;
 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
 
 final class AssetRendererTest extends UnitTestCase
 {
-    protected bool $resetSingletonInstances = true;
-    protected AssetRenderer $subject;
-    protected MockObject&EventDispatcherInterface $eventDispatcher;
-
-    public function setUp(): void
-    {
-        parent::setUp();
-        $eventDispatcher = $this->createMock(EventDispatcherInterface::class);
-        $this->subject = new AssetRenderer(null, $eventDispatcher);
-        $this->eventDispatcher = $eventDispatcher;
-    }
-
-    #[DataProviderExternal(AssetDataProvider::class, 'filesDataProvider')]
-    #[Test]
-    public function styleSheets(array $files, array $expectedResult, array $expectedMarkup): void
-    {
-        $assetCollector = GeneralUtility::makeInstance(AssetCollector::class);
-        foreach ($files as $file) {
-            [$identifier, $source, $attributes, $options] = $file;
-            $assetCollector->addStyleSheet($identifier, $source, $attributes, $options);
-        }
-        self::assertSame($expectedMarkup['css_no_prio'], $this->subject->renderStyleSheets());
-        self::assertSame($expectedMarkup['css_prio'], $this->subject->renderStyleSheets(true));
-    }
-
-    #[DataProviderExternal(AssetDataProvider::class, 'filesDataProvider')]
-    #[Test]
-    public function javaScript(array $files, array $expectedResult, array $expectedMarkup): void
+    /**
+     * cross-product of all combinations of AssetRenderer::render*() methods and priorities
+     * @return array[] [render method name, isInline, isPriority, event class]
+     */
+    public static function renderMethodsAndEventsDataProvider(): array
     {
-        $assetCollector = GeneralUtility::makeInstance(AssetCollector::class);
-        foreach ($files as $file) {
-            [$identifier, $source, $attributes, $options] = $file;
-            $assetCollector->addJavaScript($identifier, $source, $attributes, $options);
-        }
-        self::assertSame($expectedMarkup['js_no_prio'], $this->subject->renderJavaScript());
-        self::assertSame($expectedMarkup['js_prio'], $this->subject->renderJavaScript(true));
+        return [
+            ['renderInlineJavaScript', true, true, BeforeJavaScriptsRenderingEvent::class],
+            ['renderInlineJavaScript', true, false, BeforeJavaScriptsRenderingEvent::class],
+            ['renderJavaScript', false, true, BeforeJavaScriptsRenderingEvent::class],
+            ['renderJavaScript', false, false, BeforeJavaScriptsRenderingEvent::class],
+            ['renderInlineStylesheets', true, true, BeforeStylesheetsRenderingEvent::class],
+            ['renderInlineStylesheets', true, false, BeforeStylesheetsRenderingEvent::class],
+            ['renderStylesheets', false, true, BeforeStylesheetsRenderingEvent::class],
+            ['renderStylesheets', false, false, BeforeStylesheetsRenderingEvent::class],
+        ];
     }
 
-    #[DataProviderExternal(AssetDataProvider::class, 'inlineDataProvider')]
-    #[Test]
-    public function inlineJavaScript(array $sources, array $expectedResult, array $expectedMarkup): void
-    {
-        $assetCollector = GeneralUtility::makeInstance(AssetCollector::class);
-        foreach ($sources as $source) {
-            [$identifier, $source, $attributes, $options] = $source;
-            $assetCollector->addInlineJavaScript($identifier, $source, $attributes, $options);
-        }
-        self::assertSame($expectedMarkup['js_no_prio'], $this->subject->renderInlineJavaScript());
-        self::assertSame($expectedMarkup['js_prio'], $this->subject->renderInlineJavaScript(true));
-    }
-
-    #[DataProviderExternal(AssetDataProvider::class, 'inlineDataProvider')]
-    #[Test]
-    public function inlineStyleSheets(array $sources, array $expectedResult, array $expectedMarkup): void
-    {
-        $assetCollector = GeneralUtility::makeInstance(AssetCollector::class);
-        foreach ($sources as $source) {
-            [$identifier, $source, $attributes, $options] = $source;
-            $assetCollector->addInlineStyleSheet($identifier, $source, $attributes, $options);
-        }
-        self::assertSame($expectedMarkup['css_no_prio'], $this->subject->renderInlineStyleSheets());
-        self::assertSame($expectedMarkup['css_prio'], $this->subject->renderInlineStyleSheets(true));
-    }
-
-    #[DataProviderExternal(AssetDataProvider::class, 'renderMethodsAndEventsDataProvider')]
+    #[DataProvider('renderMethodsAndEventsDataProvider')]
     #[Test]
     public function beforeRenderingEvent(
         string $renderMethodName,
@@ -100,18 +54,22 @@ final class AssetRendererTest extends UnitTestCase
         bool $priority,
         string $eventClassName
     ): void {
-        $assetCollector = GeneralUtility::makeInstance(AssetCollector::class);
+        $eventDispatcher = $this->createMock(EventDispatcherInterface::class);
+        $eventDispatcher->method('dispatch')->willReturnArgument(0);
+        $assetCollector = new AssetCollector();
+        $assetRenderer = new AssetRenderer($assetCollector, $eventDispatcher);
+
         $event = new $eventClassName(
             $assetCollector,
             $isInline,
             $priority
         );
 
-        $this->eventDispatcher
+        $eventDispatcher
             ->expects(self::once())
             ->method('dispatch')
             ->with($event);
 
-        $this->subject->$renderMethodName($priority);
+        $assetRenderer->$renderMethodName($priority);
     }
 }