import importlib.util import io import json from pathlib import Path import tempfile import unittest import zipfile ROOT = Path(__file__).resolve().parents[1] spec = importlib.util.spec_from_file_location('updater', ROOT / 'persimmons/web/update-extension.py') updater = importlib.util.module_from_spec(spec) spec.loader.exec_module(updater) class UpdateTests(unittest.TestCase): def test_same_folder_preserves_identity_and_unrelated_files(self): with tempfile.TemporaryDirectory() as name: folder = Path(name) manifest = (ROOT / 'persimmons-extension/manifest.json').read_bytes() (folder / 'manifest.json').write_bytes(manifest) (folder / 'keep.txt').write_text('unrelated') raw = (ROOT / 'persimmons/web/extension.zip').read_bytes() self.assertEqual(updater.update(folder, raw), json.loads(manifest)['version']) self.assertEqual((folder / 'keep.txt').read_text(), 'unrelated') self.assertEqual((folder / 'manifest.json').read_bytes(), manifest) for bad in ('persimmons-extension/../escape.mjs', '/tmp/escape.mjs'): archive = io.BytesIO() with zipfile.ZipFile(archive, 'w') as zipped: zipped.writestr('persimmons-extension/manifest.json', manifest) zipped.writestr(bad, 'bad') with self.assertRaises(ValueError): updater.update(folder, archive.getvalue()) archive = io.BytesIO() with zipfile.ZipFile(archive, 'w') as zipped: changed = json.loads(manifest) changed['key'] = 'YWJj' zipped.writestr('persimmons-extension/manifest.json', json.dumps(changed)) with self.assertRaises(ValueError): updater.update(folder, archive.getvalue()) self.assertEqual((folder / 'manifest.json').read_bytes(), manifest)