8
8
from cStringIO import StringIO
9
9
from django .conf import settings
10
10
from django .core .exceptions import SuspiciousOperation
11
- from django .core .files .base import ContentFile
11
+ from django .core .files .base import ContentFile , File
12
12
from django .core .files .images import get_image_dimensions
13
- from django .core .files .storage import FileSystemStorage
13
+ from django .core .files .storage import FileSystemStorage , get_storage_class
14
14
from django .core .files .uploadedfile import UploadedFile
15
+ from django .core .exceptions import ImproperlyConfigured
15
16
from unittest import TestCase
16
17
try :
17
18
import threading
29
30
except ImportError :
30
31
Image = None
31
32
33
+ class GetStorageClassTests (unittest .TestCase ):
34
+ def assertRaisesErrorWithMessage (self , error , message , callable ,
35
+ * args , ** kwargs ):
36
+ self .assertRaises (error , callable , * args , ** kwargs )
37
+ try :
38
+ callable (* args , ** kwargs )
39
+ except error , e :
40
+ self .assertEqual (message , str (e ))
41
+
42
+ def test_get_filesystem_storage (self ):
43
+ """
44
+ get_storage_class returns the class for a storage backend name/path.
45
+ """
46
+ self .assertEqual (
47
+ get_storage_class ('django.core.files.storage.FileSystemStorage' ),
48
+ FileSystemStorage )
49
+
50
+ def test_get_invalid_storage_module (self ):
51
+ """
52
+ get_storage_class raises an error if the requested import don't exist.
53
+ """
54
+ self .assertRaisesErrorWithMessage (
55
+ ImproperlyConfigured ,
56
+ "NonExistingStorage isn't a storage module." ,
57
+ get_storage_class ,
58
+ 'NonExistingStorage' )
59
+
60
+ def test_get_nonexisting_storage_class (self ):
61
+ """
62
+ get_storage_class raises an error if the requested class don't exist.
63
+ """
64
+ self .assertRaisesErrorWithMessage (
65
+ ImproperlyConfigured ,
66
+ 'Storage module "django.core.files.storage" does not define a ' \
67
+ '"NonExistingStorage" class.' ,
68
+ get_storage_class ,
69
+ 'django.core.files.storage.NonExistingStorage' )
70
+
71
+ def test_get_nonexisting_storage_module (self ):
72
+ """
73
+ get_storage_class raises an error if the requested module don't exist.
74
+ """
75
+ self .assertRaisesErrorWithMessage (
76
+ ImproperlyConfigured ,
77
+ 'Error importing storage module django.core.files.non_existing_' \
78
+ 'storage: "No module named non_existing_storage"' ,
79
+ get_storage_class ,
80
+ 'django.core.files.non_existing_storage.NonExistingStorage' )
81
+
32
82
class FileStorageTests (unittest .TestCase ):
33
83
storage_class = FileSystemStorage
34
84
35
85
def setUp (self ):
36
86
self .temp_dir = tempfile .mktemp ()
37
87
os .makedirs (self .temp_dir )
38
- self .storage = self .storage_class (location = self .temp_dir )
88
+ self .storage = self .storage_class (location = self .temp_dir ,
89
+ base_url = '/test_media_url/' )
39
90
40
91
def tearDown (self ):
41
- os . rmdir (self .temp_dir )
92
+ shutil . rmtree (self .temp_dir )
42
93
43
94
def test_file_access_options (self ):
44
95
"""
@@ -57,6 +108,89 @@ def test_file_access_options(self):
57
108
self .storage .delete ('storage_test' )
58
109
self .failIf (self .storage .exists ('storage_test' ))
59
110
111
+ def test_file_save_without_name (self ):
112
+ """
113
+ File storage extracts the filename from the content object if no
114
+ name is given explicitly.
115
+ """
116
+ self .failIf (self .storage .exists ('test.file' ))
117
+
118
+ f = ContentFile ('custom contents' )
119
+ f .name = 'test.file'
120
+
121
+ storage_f_name = self .storage .save (None , f )
122
+
123
+ self .assertEqual (storage_f_name , f .name )
124
+
125
+ self .assert_ (os .path .exists (os .path .join (self .temp_dir , f .name )))
126
+
127
+ self .storage .delete (storage_f_name )
128
+
129
+ def test_file_path (self ):
130
+ """
131
+ File storage returns the full path of a file
132
+ """
133
+ self .failIf (self .storage .exists ('test.file' ))
134
+
135
+ f = ContentFile ('custom contents' )
136
+ f_name = self .storage .save ('test.file' , f )
137
+
138
+ self .assertEqual (self .storage .path (f_name ),
139
+ os .path .join (self .temp_dir , f_name ))
140
+
141
+ self .storage .delete (f_name )
142
+
143
+ def test_file_url (self ):
144
+ """
145
+ File storage returns a url to access a given file from the web.
146
+ """
147
+ self .assertEqual (self .storage .url ('test.file' ),
148
+ '%s%s' % (self .storage .base_url , 'test.file' ))
149
+
150
+ self .storage .base_url = None
151
+ self .assertRaises (ValueError , self .storage .url , 'test.file' )
152
+
153
+ def test_file_with_mixin (self ):
154
+ """
155
+ File storage can get a mixin to extend the functionality of the
156
+ returned file.
157
+ """
158
+ self .failIf (self .storage .exists ('test.file' ))
159
+
160
+ class TestFileMixin (object ):
161
+ mixed_in = True
162
+
163
+ f = ContentFile ('custom contents' )
164
+ f_name = self .storage .save ('test.file' , f )
165
+
166
+ self .assert_ (isinstance (
167
+ self .storage .open ('test.file' , mixin = TestFileMixin ),
168
+ TestFileMixin
169
+ ))
170
+
171
+ self .storage .delete ('test.file' )
172
+
173
+ def test_listdir (self ):
174
+ """
175
+ File storage returns a tuple containing directories and files.
176
+ """
177
+ self .failIf (self .storage .exists ('storage_test_1' ))
178
+ self .failIf (self .storage .exists ('storage_test_2' ))
179
+ self .failIf (self .storage .exists ('storage_dir_1' ))
180
+
181
+ f = self .storage .save ('storage_test_1' , ContentFile ('custom content' ))
182
+ f = self .storage .save ('storage_test_2' , ContentFile ('custom content' ))
183
+ os .mkdir (os .path .join (self .temp_dir , 'storage_dir_1' ))
184
+
185
+ dirs , files = self .storage .listdir ('' )
186
+ self .assertEqual (set (dirs ), set ([u'storage_dir_1' ]))
187
+ self .assertEqual (set (files ),
188
+ set ([u'storage_test_1' , u'storage_test_2' ]))
189
+
190
+ self .storage .delete ('storage_test_1' )
191
+ self .storage .delete ('storage_test_2' )
192
+ os .rmdir (os .path .join (self .temp_dir , 'storage_dir_1' ))
193
+
60
194
def test_file_storage_prevents_directory_traversal (self ):
61
195
"""
62
196
File storage prevents directory traversal (files can only be accessed if
0 commit comments