from __future__ import annotations import tempfile import unittest from concurrent.futures import ThreadPoolExecutor from pathlib import Path from web.routers.files import _numbered_upload_name, _replace_upload, _write_upload_without_overwrite class FileUploadConflictTests(unittest.TestCase): def test_number_is_inserted_before_complete_extension(self): self.assertEqual(_numbered_upload_name("data.tar.gz", 2), "data (2).tar.gz") self.assertEqual(_numbered_upload_name("报告", 1), "报告 (1)") self.assertEqual(_numbered_upload_name(".env", 1), ".env (1)") def test_existing_file_is_preserved(self): with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) (root / "报告.pdf").write_bytes(b"old") saved = _write_upload_without_overwrite(root, "报告.pdf", b"new") self.assertEqual(saved.name, "报告 (1).pdf") self.assertEqual((root / "报告.pdf").read_bytes(), b"old") self.assertEqual(saved.read_bytes(), b"new") def test_concurrent_uploads_get_distinct_names(self): with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) with ThreadPoolExecutor(max_workers=4) as pool: saved = list(pool.map( lambda i: _write_upload_without_overwrite(root, "same.txt", str(i).encode()), range(4), )) self.assertEqual(len({path.name for path in saved}), 4) self.assertEqual(len(list(root.glob("same*.txt"))), 4) def test_explicit_replace_changes_only_target(self): with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) target = root / "target.txt" target.write_bytes(b"old") _replace_upload(target, b"new") self.assertEqual(target.read_bytes(), b"new") self.assertFalse(list(root.glob(".zcbot-upload-*"))) if __name__ == "__main__": unittest.main()