summaryrefslogtreecommitdiff
path: root/tests/forms_tests/field_tests/test_filepathfield.py
blob: 116600484abb0a74392023b67bd0c582128c3841 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import os.path
import tempfile

from django.core.exceptions import ValidationError
from django.forms import FilePathField
from django.test import SimpleTestCase

PATH = os.path.dirname(os.path.abspath(__file__))


def fix_os_paths(x):
    if isinstance(x, str):
        return x.removeprefix(PATH).replace("\\", "/")
    elif isinstance(x, tuple):
        return tuple(fix_os_paths(list(x)))
    elif isinstance(x, list):
        return [fix_os_paths(y) for y in x]
    else:
        return x


class FilePathFieldTest(SimpleTestCase):
    expected_choices = [
        ("/filepathfield_test_dir/__init__.py", "__init__.py"),
        ("/filepathfield_test_dir/a.py", "a.py"),
        ("/filepathfield_test_dir/ab.py", "ab.py"),
        ("/filepathfield_test_dir/b.py", "b.py"),
        ("/filepathfield_test_dir/c/__init__.py", "__init__.py"),
        ("/filepathfield_test_dir/c/d.py", "d.py"),
        ("/filepathfield_test_dir/c/e.py", "e.py"),
        ("/filepathfield_test_dir/c/f/__init__.py", "__init__.py"),
        ("/filepathfield_test_dir/c/f/g.py", "g.py"),
        ("/filepathfield_test_dir/h/__init__.py", "__init__.py"),
        ("/filepathfield_test_dir/j/__init__.py", "__init__.py"),
    ]
    path = os.path.join(PATH, "filepathfield_test_dir") + "/"

    def assertChoices(self, field, expected_choices):
        self.assertEqual(fix_os_paths(field.choices), expected_choices)

    def test_fix_os_paths(self):
        self.assertEqual(fix_os_paths(self.path), ("/filepathfield_test_dir/"))

    def test_nonexistent_path(self):
        with self.assertRaisesMessage(FileNotFoundError, "nonexistent"):
            FilePathField(path="nonexistent")

    def test_no_options(self):
        f = FilePathField(path=self.path)
        expected = [
            ("/filepathfield_test_dir/README", "README"),
        ] + self.expected_choices[:4]
        self.assertChoices(f, expected)

    def test_clean(self):
        f = FilePathField(path=self.path)
        msg = "'Select a valid choice. a.py is not one of the available choices.'"
        with self.assertRaisesMessage(ValidationError, msg):
            f.clean("a.py")
        self.assertEqual(
            fix_os_paths(f.clean(self.path + "a.py")), "/filepathfield_test_dir/a.py"
        )

    def test_match(self):
        f = FilePathField(path=self.path, match=r"^.*?\.py$")
        self.assertChoices(f, self.expected_choices[:4])

    def test_recursive(self):
        f = FilePathField(path=self.path, recursive=True, match=r"^.*?\.py$")
        expected = [
            ("/filepathfield_test_dir/__init__.py", "__init__.py"),
            ("/filepathfield_test_dir/a.py", "a.py"),
            ("/filepathfield_test_dir/ab.py", "ab.py"),
            ("/filepathfield_test_dir/b.py", "b.py"),
            ("/filepathfield_test_dir/c/__init__.py", "c/__init__.py"),
            ("/filepathfield_test_dir/c/d.py", "c/d.py"),
            ("/filepathfield_test_dir/c/e.py", "c/e.py"),
            ("/filepathfield_test_dir/c/f/__init__.py", "c/f/__init__.py"),
            ("/filepathfield_test_dir/c/f/g.py", "c/f/g.py"),
            ("/filepathfield_test_dir/h/__init__.py", "h/__init__.py"),
            ("/filepathfield_test_dir/j/__init__.py", "j/__init__.py"),
        ]
        self.assertChoices(f, expected)

    def test_allow_folders(self):
        f = FilePathField(path=self.path, allow_folders=True, allow_files=False)
        self.assertChoices(
            f,
            [
                ("/filepathfield_test_dir/c", "c"),
                ("/filepathfield_test_dir/h", "h"),
                ("/filepathfield_test_dir/j", "j"),
            ],
        )

    def test_recursive_no_folders_or_files(self):
        f = FilePathField(
            path=self.path, recursive=True, allow_folders=False, allow_files=False
        )
        self.assertChoices(f, [])

    def test_set_choices_picks_up_new_files(self):
        with tempfile.TemporaryDirectory() as tmp_dir:
            f = FilePathField(path=tmp_dir)
            self.assertEqual(f.choices, [])
            tmp_file = os.path.join(tmp_dir, "new_file.txt")
            open(tmp_file, "w").close()
            f.set_choices()
            self.assertIn((tmp_file, "new_file.txt"), f.choices)
            self.assertIn((tmp_file, "new_file.txt"), f.widget.choices)

    def test_recursive_folders_without_files(self):
        f = FilePathField(
            path=self.path, recursive=True, allow_folders=True, allow_files=False
        )
        self.assertChoices(
            f,
            [
                ("/filepathfield_test_dir/c", "c"),
                ("/filepathfield_test_dir/h", "h"),
                ("/filepathfield_test_dir/j", "j"),
                ("/filepathfield_test_dir/c/f", "c/f"),
            ],
        )