From 5d00faa6bb52153341d71efc0394fd1e1e16f5ca Mon Sep 17 00:00:00 2001 From: Allison Karlitskaya Date: Fri, 8 Dec 2023 09:52:35 +0100 Subject: [PATCH] bridge: Add back support for x.min.js files We removed support for `.min.` filenames because we thought that nobody was using it anymore, but there are still external packages that make use of it. Add it back again, but only for the case where the non-minified version isn't present. The minified version can always be explicitly requested via its full filename (minus `.gz`, if applicable). Add a bit of debugging output and some test cases to make sure we handle the combinations properly. Fixes https://issues.redhat.com/browse/RHEL-18861 --- src/cockpit/packages.py | 13 +++++++++- test/pytest/test_packages.py | 46 ++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/cockpit/packages.py b/src/cockpit/packages.py index f43053ea25f6..66c7ac970b0e 100644 --- a/src/cockpit/packages.py +++ b/src/cockpit/packages.py @@ -266,11 +266,22 @@ def ensure_scanned(self) -> None: # Accept-Language is case-insensitive and uses '-' to separate variants lower_locale = locale.lower().replace('_', '-') + logger.debug('Adding translation %r %r -> %r', basename, lower_locale, name) self.translations[f'{basename}.js'][lower_locale] = name else: - basename = name[:-3] if name.endswith('.gz') else name + # strip out trailing '.gz' components + basename = re.sub('.gz$', '', name) + logger.debug('Adding content %r -> %r', basename, name) self.files[basename] = name + # If we see a filename like `x.min.js` we want to also offer it + # at `x.js`, but only if `x.js(.gz)` itself is not present. + # Note: this works for both the case where we found the `x.js` + # first (it's already in the map) and also if we find it second + # (it will be replaced in the map by the line just above). + # See https://github.com/cockpit-project/cockpit/pull/19716 + self.files.setdefault(basename.replace('.min.', '.'), name) + # support old cockpit-po-plugin which didn't write po.manifest.??.js if not self.translations['po.manifest.js']: self.translations['po.manifest.js'] = self.translations['po.js'] diff --git a/test/pytest/test_packages.py b/test/pytest/test_packages.py index e6d7c75c7f65..4170f5d50b77 100644 --- a/test/pytest/test_packages.py +++ b/test/pytest/test_packages.py @@ -239,3 +239,49 @@ def test_translation(pkgdir): assert b'eins\n' in contents assert b'zwo\n' in contents assert b'zwei\n' not in contents + + +def test_filename_mangling(pkgdir): + make_package(pkgdir, 'one') + + # test various filename variations + (pkgdir / 'one' / 'one.js').write_text('this is one.js') + (pkgdir / 'one' / 'two.js.gz').write_text('this is two.js') + (pkgdir / 'one' / 'three.min.js.gz').write_text('this is three.js') + (pkgdir / 'one' / 'four.min.js').write_text('this is four.js') + + packages = Packages() + encodings = set() + + for name in ['one', 'two', 'three', 'four']: + document = packages.load_path(f'/one/{name}.js', {}) + assert document.data.read().decode() == f'this is {name}.js' + assert '/javascript' in document.content_type + encodings.add(document.content_encoding) + + assert encodings == {None, 'gzip'} # make sure we saw both compressed and uncompressed + + +def test_overlapping_minified(pkgdir): + make_package(pkgdir, 'one') + (pkgdir / 'one' / 'one.min.js').write_text('min') + (pkgdir / 'one' / 'one.js').write_text('max') + + # try the other way around in hope of listing the files in reverse order + (pkgdir / 'one' / 'two.js').write_text('max') + (pkgdir / 'one' / 'two.min.js').write_text('min') + + packages = Packages() + + # if both files are present, we should find the original one + document = packages.load_path('/one/one.js', {}) + assert document.data.read().decode() == 'max' + document = packages.load_path('/one/two.js', {}) + assert document.data.read().decode() == 'max' + + # but requesting .min. explicitly will load it + document = packages.load_path('/one/one.min.js', {}) + assert document.data.read().decode() == 'min' + document = packages.load_path('/one/two.min.js', {}) + assert document.data.read().decode() == 'min' +