You are here

public function ConfirmClassyCopiesTest::testClassyCopies in Drupal 9

Same name and namespace in other branches
  1. 8 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 59

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.");
  }
}