Skip to content
Snippets Groups Projects
Verified Commit a6460005 authored by Dave Long's avatar Dave Long
Browse files

Issue #3370828 by catch, longwave, sime, Chi, lauriii, larowlan, agarzola:...

Issue #3370828 by catch, longwave, sime, Chi, lauriii, larowlan, agarzola: Ensure that edge caches are busted on deployments for css/js aggregates

(cherry picked from commit 3041dbfe)
parent 83da1db4
No related branches found
No related tags found
20 merge requests!11628Update file MediaLibraryWidget.php,!7564Revert "Issue #3364773 by roshnichordiya, Chris Matthews, thakurnishant_06,...,!5752Issue #3275828 by joachim, quietone, bradjones1, Berdir: document the reason...,!5627Issue #3261805: Field not saved when change of 0 on string start,!5427Issue #3338518: send credentials in ajax if configured in CORS settings.,!5395Issue #3387916 by fjgarlin, Spokje: Each GitLab job exposes user email,!5217Issue #3386607 by alexpott: Improve spell checking in commit-code-check.sh,!5064Issue #3379522 by finnsky, Gauravvvv, kostyashupenko, smustgrave, Chi: Revert...,!5040SDC ComponentElement: Transform slots scalar values to #plain_text instead of throwing an exception,!4958Issue #3392147: Whitelist IP for a Ban module.,!4894Issue #3280279: Add API to allow sites to opt in to upload SVG images in CKEditor 5,!4857Issue #3336994: StringFormatter always displays links to entity even if the user in context does not have access,!4856Issue #3336994: StringFormatter always displays links to entity even if the user in context does not have access,!4788Issue #3272985: RSS Feed header reverts to text/html when cached,!4716Issue #3362929: Improve 400 responses for broken/invalid image style routes,!4553Draft: Issue #2980951: Permission to see own unpublished comments in comment thread,!3679Issue #115801: Allow password on registration without disabling e-mail verification,!3106Issue #3017548: "Filtered HTML" text format does not support manual teaser break (<!--break-->),!925Issue #2339235: Remove taxonomy hard dependency on node module,!872Draft: Issue #3221319: Race condition when creating menu links and editing content deletes menu links
......@@ -36,6 +36,12 @@ protected function generateHash(array $group): string {
];
foreach ($group['items'] as $key => $asset) {
$normalized['asset_group']['items'][$key] = array_diff_key($asset, $group_keys, $omit_keys);
// If the version is set to -1, this means there is no version in the
// library definition. To ensure unique hashes when unversioned files
// change, replace the version with a hash of the file contents.
if ($asset['version'] === -1) {
$normalized['asset_group']['items'][$key]['version'] = hash('xxh64', file_get_contents($asset['data']));
}
}
// The asset array ensures that a valid hash can only be generated via the
// same code base. Additionally use the hash salt to ensure that hashes are
......
name: 'Unversioned assets test'
type: module
description: 'Tests that aggregates change when unversioned assets change'
package: Testing
version: VERSION
<?php
/**
* @file
* Helper module for unversioned asset test.
*/
/**
* Implements hook_library_info_build().
*/
function unversioned_assets_test_library_info_alter(&$libraries, $extension) {
if ($extension === 'system') {
// Remove the version and provide an additional CSS file we can alter the
// contents of .
unset($libraries['base']['version']);
$libraries['base']['css']['component']['public://test.css'] = ['weight' => -10];
}
}
<?php
namespace Drupal\FunctionalTests\Asset;
use Drupal\Tests\BrowserTestBase;
/**
* Tests asset aggregation.
*
* @group asset
*/
class UnversionedAssetTest extends BrowserTestBase {
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* The file assets path settings value.
*/
protected $fileAssetsPath;
/**
* {@inheritdoc}
*/
protected static $modules = ['system', 'unversioned_assets_test'];
/**
* Tests that unversioned assets cause a new filename when changed.
*/
public function testUnversionedAssets(): void {
$this->fileAssetsPath = $this->publicFilesDirectory;
file_put_contents('public://test.css', '.original-content{display:none;}');
// Test aggregation with a custom file_assets_path.
$this->config('system.performance')->set('css', [
'preprocess' => TRUE,
'gzip' => TRUE,
])->save();
$this->config('system.performance')->set('js', [
'preprocess' => TRUE,
'gzip' => TRUE,
])->save();
// Ensure that the library discovery cache is empty before the page is
// requested and that updated asset URLs are rendered.
\Drupal::service('cache.data')->deleteAll();
\Drupal::service('cache.page')->deleteAll();
$this->drupalGet('<front>');
$session = $this->getSession();
$page = $session->getPage();
$style_elements = $page->findAll('xpath', '//link[@rel="stylesheet"]');
$this->assertNotEmpty($style_elements);
$href = NULL;
foreach ($style_elements as $element) {
if ($element->hasAttribute('href')) {
$href = $element->getAttribute('href');
$url = $this->getAbsoluteUrl($href);
// Not every script or style on a page is aggregated.
if (!str_contains($url, $this->fileAssetsPath)) {
continue;
}
$session = $this->getSession();
$session->visit($url);
$this->assertSession()->statusCodeEquals(200);
$aggregate = $session = $session->getPage()->getContent();
$this->assertStringContainsString('original-content', $aggregate);
$this->assertStringNotContainsString('extra-stuff', $aggregate);
}
}
$file = file_get_contents('public://test.css') . '.extra-stuff{display:none;}';
file_put_contents('public://test.css', $file);
// Clear the library discovery and page caches again so that new URLs are
// generated.
\Drupal::service('cache.data')->deleteAll();
\Drupal::service('cache.page')->deleteAll();
$this->drupalGet('<front>');
$session = $this->getSession();
$page = $session->getPage();
$style_elements = $page->findAll('xpath', '//link[@rel="stylesheet"]');
$this->assertNotEmpty($style_elements);
foreach ($style_elements as $element) {
if ($element->hasAttribute('href')) {
$new_href = $element->getAttribute('href');
$this->assertNotSame($new_href, $href);
$url = $this->getAbsoluteUrl($new_href);
// Not every script or style on a page is aggregated.
if (!str_contains($url, $this->fileAssetsPath)) {
continue;
}
$session = $this->getSession();
$session->visit($url);
$this->assertSession()->statusCodeEquals(200);
$aggregate = $session = $session->getPage()->getContent();
$this->assertStringContainsString('original-content', $aggregate);
$this->assertStringContainsString('extra-stuff', $aggregate);
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment