|
| 1 | +import string |
| 2 | + |
| 3 | +from django.test import TestCase |
| 4 | + |
| 5 | +from filer.utils.files import get_valid_filename |
| 6 | + |
| 7 | + |
| 8 | +class GetValidFilenameTest(TestCase): |
| 9 | + def test_short_filename_remains_unchanged(self): |
| 10 | + """ |
| 11 | + Test that a filename under the maximum length remains unchanged. |
| 12 | + """ |
| 13 | + original = "example.jpg" |
| 14 | + result = get_valid_filename(original) |
| 15 | + self.assertEqual(result, "example.jpg") |
| 16 | + |
| 17 | + def test_long_filename_is_truncated_and_suffix_appended(self): |
| 18 | + """ |
| 19 | + Test that a filename longer than the maximum allowed length is truncated and a random |
| 20 | + hexadecimal suffix is appended. The final filename must not exceed 255 characters. |
| 21 | + """ |
| 22 | + # Create a filename that is much longer than 255 characters. |
| 23 | + base = "a" * 300 # 300 characters |
| 24 | + original = f"{base}.jpg" |
| 25 | + result = get_valid_filename(original) |
| 26 | + # Assert that the result is within the maximum allowed length. |
| 27 | + self.assertTrue(len(result) <= 255, "Filename exceeds 255 characters.") |
| 28 | + |
| 29 | + # When truncated, the filename should end with a random hexadecimal suffix of length 16. |
| 30 | + # We check that the suffix contains only hexadecimal digits. |
| 31 | + random_suffix = result[-16:] |
| 32 | + valid_hex_chars = set(string.hexdigits) |
| 33 | + self.assertTrue(all(c in valid_hex_chars for c in random_suffix), |
| 34 | + "The suffix is not a valid hexadecimal string.") |
| 35 | + |
| 36 | + def test_filename_with_extension_preserved(self): |
| 37 | + """ |
| 38 | + Test that the file extension is preserved (and slugified) after processing. |
| 39 | + """ |
| 40 | + original = "This is a test IMAGE.JPG" |
| 41 | + result = get_valid_filename(original) |
| 42 | + # Since slugification converts characters to lowercase, we expect ".jpg" |
| 43 | + self.assertTrue(result.endswith(".jpg"), |
| 44 | + "File extension was not preserved correctly.") |
| 45 | + |
| 46 | + def test_unicode_characters(self): |
| 47 | + """ |
| 48 | + Test that filenames with Unicode characters are handled correctly and result in a valid filename. |
| 49 | + """ |
| 50 | + original = "fiłęñâmé_üñîçødé.jpeg" |
| 51 | + result = get_valid_filename(original) |
| 52 | + # Verify that the result ends with the expected extension and contains only allowed characters. |
| 53 | + self.assertTrue(result.endswith(".jpeg"), "File extension is not preserved for unicode filename.") |
| 54 | + # Optionally, check that no unexpected characters remain (depends on your slugify behavior). |
| 55 | + for char in result: |
| 56 | + # Allow only alphanumeric characters, underscores, dashes, and the dot. |
| 57 | + self.assertIn(char, string.ascii_lowercase + string.digits + "._-", |
| 58 | + f"Unexpected character '{char}' found in filename.") |
| 59 | + |
| 60 | + def test_edge_case_exact_length(self): |
| 61 | + """ |
| 62 | + Test an edge case where the filename is exactly the maximum allowed length. |
| 63 | + The function should leave such a filename unchanged. |
| 64 | + """ |
| 65 | + # Create a filename that is exactly 255 characters long. |
| 66 | + base = "b" * 250 # 250 characters for base |
| 67 | + original = f"{base}.png" # This may reach exactly or slightly above 255 depending on slugification |
| 68 | + result = get_valid_filename(original) |
| 69 | + # We check that the final result does not exceed 255 characters. |
| 70 | + self.assertTrue(len(result) <= 255, |
| 71 | + "Edge case filename exceeds the maximum allowed length.") |
0 commit comments