| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- """Validator tests for FAT32/exFAT-safe print filenames (#1540)."""
- import pytest
- from backend.app.utils.filename import (
- INVALID_FILENAME_CHARS,
- InvalidFilenameError,
- validate_print_filename,
- )
- class TestValidatePrintFilename:
- @pytest.mark.parametrize(
- "name",
- [
- "model.3mf",
- "Bersaglio.gcode.3mf",
- "Plate 1.3mf",
- "プリント.3mf",
- "model_v2-final.3mf",
- "a.3mf",
- ],
- )
- def test_valid_names_accepted(self, name: str) -> None:
- validate_print_filename(name)
- @pytest.mark.parametrize("char", list(INVALID_FILENAME_CHARS))
- def test_each_invalid_char_rejected(self, char: str) -> None:
- with pytest.raises(InvalidFilenameError) as exc_info:
- validate_print_filename(f"L{char}R.3mf")
- assert exc_info.value.char == char
- def test_pipe_from_issue_1540(self) -> None:
- """The exact reproducer from the bug report."""
- with pytest.raises(InvalidFilenameError) as exc_info:
- validate_print_filename("L|R.3mf")
- assert exc_info.value.char == "|"
- @pytest.mark.parametrize("name", ["", " ", " "])
- def test_empty_rejected(self, name: str) -> None:
- with pytest.raises(InvalidFilenameError, match="empty"):
- validate_print_filename(name)
- @pytest.mark.parametrize("name", [".", ".."])
- def test_dot_names_rejected(self, name: str) -> None:
- with pytest.raises(InvalidFilenameError):
- validate_print_filename(name)
- def test_control_char_rejected(self) -> None:
- with pytest.raises(InvalidFilenameError, match="control"):
- validate_print_filename("file\x01.3mf")
- @pytest.mark.parametrize("name", ["file.3mf.", "file.3mf "])
- def test_trailing_space_or_dot_rejected(self, name: str) -> None:
- with pytest.raises(InvalidFilenameError, match="space or dot"):
- validate_print_filename(name)
- def test_too_long_rejected(self) -> None:
- with pytest.raises(InvalidFilenameError, match="bytes"):
- validate_print_filename("a" * 256)
- def test_unicode_byte_length_not_codepoint(self) -> None:
- """255 multi-byte codepoints exceeds 255 bytes — must reject."""
- # 'ä' is 2 bytes in UTF-8
- with pytest.raises(InvalidFilenameError, match="bytes"):
- validate_print_filename("ä" * 200)
|