function ConfirmClassyCopiesTest::testClassyCopies

Same name in other branches
  1. 8.9.x core/tests/Drupal/KernelTests/Core/Theme/ConfirmClassyCopiesTest.php \Drupal\KernelTests\Core\Theme\ConfirmClassyCopiesTest::testClassyCopies()

Confirms that files copied from Classy have not been altered.

The /classy subdirectory in a theme's css, js and images directories is for unaltered copies of files from Classy. If a file in that subdirectory has changed, then it is custom to that theme and should be moved to a different directory. Additional information can be found in the README.txt of each of those /classy subdirectories.

@dataProvider providerTestClassyCopies

Parameters

string $theme: The theme being tested.

string $path_replace: A string to replace paths found in CSS so relative URLs don't cause the hash to differ.

string[] $filenames: Provides list of every asset copied from Classy.

File

core/tests/Drupal/KernelTests/Core/Theme/ConfirmClassyCopiesTest.php, line 60

Class

ConfirmClassyCopiesTest
Confirms that theme assets copied from Classy have not been changed.

Namespace

Drupal\KernelTests\Core\Theme

Code

public function testClassyCopies($theme, $path_replace, array $filenames) {
    $theme_path = $this->container
        ->get('extension.list.theme')
        ->getPath($theme);
    foreach ([
        'images',
        'css',
        'js',
        'templates',
    ] as $sub_folder) {
        $asset_path = "{$theme_path}/{$sub_folder}/classy";
        // If a theme has completely customized all files of a type there is
        // potentially no Classy subdirectory for that type. Tests can be skipped
        // for that type.
        if (!file_exists($asset_path)) {
            $this->assertEmpty($filenames[$sub_folder]);
            continue;
        }
        // Create iterators to collect all files in a asset directory.
        $directory = new \RecursiveDirectoryIterator($asset_path, \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::SKIP_DOTS);
        $iterator = new \RecursiveIteratorIterator($directory);
        $filecount = 0;
        foreach ($iterator as $fileinfo) {
            $filename = $fileinfo->getFilename();
            if ($filename === 'README.txt') {
                continue;
            }
            $filecount++;
            // Replace paths in the contents so the hash will match Classy's hashes.
            $contents = file_get_contents($fileinfo->getPathname());
            $contents = str_replace('(' . $path_replace, '(../../../../', $contents);
            $contents = str_replace('(../../../images/classy/icons', '(../../images/icons', $contents);
            preg_match_all("/attach_library\\('.+\\/classy\\.(.+)'/", $contents, $classy_attach_library_matches);
            if (!empty($classy_attach_library_matches[0])) {
                $library_module = $classy_attach_library_matches[1][0];
                $contents = str_replace("'{$theme}/classy.{$library_module}'", "'classy/{$library_module}'", $contents);
            }
            $this->assertContains($filename, $filenames[$sub_folder], "{$sub_folder} file: {$filename} not present.");
            $this->assertSame($this->getClassyHash($sub_folder, $filename), md5($contents), "{$filename} is in the theme's /classy subdirectory, but the file contents no longer match the original file from Classy. This should be moved to a new directory and libraries should be updated. The file can be removed from the data provider.");
        }
        $this->assertCount($filecount, $filenames[$sub_folder], "Different count for {$sub_folder} files in the /classy subdirectory. If a file was added to /classy, it shouldn't have been. If it was intentionally removed, it should also be removed from this test's data provider.");
    }
}

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