Completed
Pull Request — master (#81)
by
unknown
01:15
created

TestModel.test_variations()   B

Complexity

Conditions 3

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 2 Features 1
Metric Value
c 6
b 2
f 1
dl 0
loc 30
rs 8.8571
cc 3
1
# coding: utf-8
2
from __future__ import absolute_import, unicode_literals
3
4
import filecmp
5
import os
6
import pytest
7
import shutil
8
import uuid
9
10
11
class UUID4Monkey(object):
12
    hex = '653d1c6863404b9689b75fa930c9d0a0'
13
14
15
uuid.__dict__['uuid4'] = lambda: UUID4Monkey()
16
17
import django  # NoQA
18
from django.conf import settings  # NoQA
19
from django.core.files import File  # NoQA
20
from django.test import TestCase  # NoQA
21
from django.contrib.auth.models import User  # NoQA
22
23
from .models import (
24
    SimpleModel, ResizeModel, AdminDeleteModel,
25
    ThumbnailModel, ResizeCropModel, AutoSlugClassNameDirModel,
26
    UUIDModel,
27
    UtilVariationsModel,
28
    ThumbnailWithoutDirectoryModel,
29
    CustomRenderVariationsModel,
30
    CustomRenderVariationsNotReturningBoolModel)  # NoQA
31
32
IMG_DIR = os.path.join(settings.MEDIA_ROOT, 'img')
33
34
FIXTURE_DIR = os.path.join(
35
    os.path.dirname(os.path.abspath(__file__)),
36
    'fixtures'
37
)
38
39
40
class TestStdImage(TestCase):
41
    def setUp(self):
42
        User.objects.create_superuser('admin', '[email protected]', 'admin')
43
        self.client.login(username='admin', password='admin')
44
45
        self.fixtures = {}
46
        fixture_paths = os.listdir(FIXTURE_DIR)
47
        for fixture_filename in fixture_paths:
48
            fixture_path = os.path.join(FIXTURE_DIR, fixture_filename)
49
            if os.path.isfile(fixture_path):
50
                f = open(fixture_path, 'rb')
51
                self.fixtures[fixture_filename] = File(f)
52
53
    def tearDown(self):
54
        """Close all open fixtures and delete everything from media"""
55
        for fixture in list(self.fixtures.values()):
56
            fixture.close()
57
58
        for root, dirs, files in os.walk(settings.MEDIA_ROOT, topdown=False):
59
            for name in files:
60
                os.remove(os.path.join(root, name))
61
            for name in dirs:
62
                os.rmdir(os.path.join(root, name))
63
64
65
class TestModel(TestStdImage):
66
    """Tests StdImage ModelField"""
67
68
    def test_simple(self):
69
        """Tests if Field behaves just like Django's ImageField."""
70
        instance = SimpleModel.objects.create(image=self.fixtures['100.gif'])
71
        target_file = os.path.join(IMG_DIR, '100.gif')
72
        source_file = os.path.join(FIXTURE_DIR, '100.gif')
73
74
        self.assertEqual(SimpleModel.objects.count(), 1)
75
        self.assertEqual(SimpleModel.objects.get(pk=1), instance)
76
77
        self.assertTrue(os.path.exists(target_file))
78
79
        self.assertTrue(filecmp.cmp(source_file, target_file))
80
81
    def test_variations(self):
82
        """Adds image and checks filesystem as well as width and height."""
83
        instance = ResizeModel.objects.create(
84
            image=self.fixtures['600x400.jpg']
85
        )
86
87
        source_file = os.path.join(FIXTURE_DIR, '600x400.jpg')
88
89
        self.assertTrue(os.path.exists(os.path.join(IMG_DIR, 'image.jpg')))
90
        self.assertEqual(instance.image.width, 600)
91
        self.assertEqual(instance.image.height, 400)
92
        path = os.path.join(IMG_DIR, 'image.jpg')
93
        assert filecmp.cmp(source_file, path)
94
95
        path = os.path.join(IMG_DIR, 'image.medium.jpg')
96
        assert os.path.exists(path)
97
        self.assertEqual(instance.image.medium.width, 400)
98
        self.assertLessEqual(instance.image.medium.height, 400)
99
        self.assertFalse(filecmp.cmp(
100
            source_file,
101
            os.path.join(IMG_DIR, 'image.medium.jpg')))
102
103
        self.assertTrue(os.path.exists(
104
            os.path.join(IMG_DIR, 'image.thumbnail.jpg'))
105
        )
106
        self.assertEqual(instance.image.thumbnail.width, 100)
107
        self.assertLessEqual(instance.image.thumbnail.height, 75)
108
        self.assertFalse(filecmp.cmp(
109
            source_file,
110
            os.path.join(IMG_DIR, 'image.thumbnail.jpg'))
111
        )
112
113
    def test_cropping(self):
114
        instance = ResizeCropModel.objects.create(
115
            image=self.fixtures['600x400.jpg']
116
        )
117
        self.assertEqual(instance.image.thumbnail.width, 150)
118
        self.assertEqual(instance.image.thumbnail.height, 150)
119
120
    def test_variations_override(self):
121
        source_file = os.path.join(FIXTURE_DIR, '600x400.jpg')
122
        target_file = os.path.join(IMG_DIR, 'image.thumbnail.jpg')
123
        os.mkdir(IMG_DIR)
124
        shutil.copyfile(source_file, target_file)
125
        ResizeModel.objects.create(
126
            image=self.fixtures['600x400.jpg']
127
        )
128
        thumbnail_path = os.path.join(IMG_DIR, 'image.thumbnail.jpg')
129
        assert os.path.exists(thumbnail_path)
130
        thumbnail_path = os.path.join(IMG_DIR, 'image.thumbnail_1.jpg')
131
        assert not os.path.exists(thumbnail_path)
132
133
    def test_delete_thumbnail(self):
134
        """Delete an image with thumbnail"""
135
        obj = ThumbnailModel.objects.create(
136
            image=self.fixtures['100.gif']
137
        )
138
        obj.image.delete()
139
        path = os.path.join(IMG_DIR, 'image.gif')
140
        assert not os.path.exists(path)
141
142
        path = os.path.join(IMG_DIR, 'image.thumbnail.gif')
143
        assert not os.path.exists(path)
144
145
    def test_fore_min_size(self):
146
        self.client.post('/admin/tests/forceminsizemodel/add/', {
147
            'image': self.fixtures['100.gif'],
148
        })
149
        path = os.path.join(IMG_DIR, 'image.gif')
150
        assert not os.path.exists(path)
151
152
    def test_thumbnail_save_without_directory(self):
153
        obj = ThumbnailWithoutDirectoryModel.objects.create(
154
            image=self.fixtures['100.gif']
155
        )
156
        obj.save()
157
        # Our model saves the images directly into the MEDIA_ROOT directory
158
        # not IMG_DIR, under a custom name
159
        original = os.path.join(settings.MEDIA_ROOT, 'custom.gif')
160
        thumbnail = os.path.join(settings.MEDIA_ROOT, 'custom.thumbnail.gif')
161
        assert os.path.exists(original)
162
        assert os.path.exists(thumbnail)
163
164
    def test_custom_render_variations(self):
165
        instance = CustomRenderVariationsModel.objects.create(
166
            image=self.fixtures['600x400.jpg']
167
        )
168
        # Image size must be 100x100 despite variations settings
169
        assert instance.image.thumbnail.width == 100
170
        assert instance.image.thumbnail.height == 100
171
172
    def test_custom_render_variations_not_returning_bool(self):
173
        with pytest.raises(TypeError) as exc_info:
174
            CustomRenderVariationsNotReturningBoolModel.objects.create(
175
                image=self.fixtures['600x400.jpg']
176
            )
177
        error_message = (
178
            '"render_variations" should return a boolean,'
179
            ' but returned %s'
180
        ) % type(None)
181
        assert str(exc_info.value) == error_message
182
183
184
class TestUtils(TestStdImage):
185
    """Tests Utils"""
186
187
    def test_deletion_singnal_receiver(self):
188
        obj = SimpleModel.objects.create(
189
            image=self.fixtures['100.gif']
190
        )
191
        obj.delete()
192
        self.assertFalse(
193
            os.path.exists(os.path.join(IMG_DIR, 'image.gif'))
194
        )
195
196
    def test_pre_save_delete_callback_clear(self):
197
        AdminDeleteModel.objects.create(
198
            image=self.fixtures['100.gif']
199
        )
200
        if django.VERSION >= (1, 9):
201
            self.client.post('/admin/tests/admindeletemodel/1/change/', {
202
                'image-clear': 'checked',
203
            })
204
        else:
205
            self.client.post('/admin/tests/admindeletemodel/1/', {
206
                'image-clear': 'checked',
207
            })
208
        self.assertFalse(
209
            os.path.exists(os.path.join(IMG_DIR, 'image.gif'))
210
        )
211
212
    def test_pre_save_delete_callback_new(self):
213
        AdminDeleteModel.objects.create(
214
            image=self.fixtures['100.gif']
215
        )
216
        if django.VERSION >= (1, 9):
217
            self.client.post('/admin/tests/admindeletemodel/1/change/', {
218
                'image': self.fixtures['600x400.jpg'],
219
            })
220
        else:
221
            self.client.post('/admin/tests/admindeletemodel/1/', {
222
                'image': self.fixtures['600x400.jpg'],
223
            })
224
        self.assertFalse(
225
            os.path.exists(os.path.join(IMG_DIR, 'image.gif'))
226
        )
227
228
    def test_upload_to_auto_slug_class_name_dir(self):
229
        AutoSlugClassNameDirModel.objects.create(
230
            name='foo bar',
231
            image=self.fixtures['100.gif']
232
        )
233
        file_path = os.path.join(
234
            settings.MEDIA_ROOT,
235
            'autoslugclassnamedirmodel',
236
            'foo-bar.gif'
237
        )
238
        self.assertTrue(os.path.exists(file_path))
239
240
    def test_upload_to_uuid(self):
241
        UUIDModel.objects.create(image=self.fixtures['100.gif'])
242
        file_path = os.path.join(
243
            IMG_DIR,
244
            '653d1c6863404b9689b75fa930c9d0a0.gif'
245
        )
246
        self.assertTrue(os.path.exists(file_path))
247
248
    def test_render_variations_callback(self):
249
        UtilVariationsModel.objects.create(image=self.fixtures['100.gif'])
250
        file_path = os.path.join(
251
            IMG_DIR,
252
            'image.thumbnail.gif'
253
        )
254
        self.assertTrue(os.path.exists(file_path))
255
256
257
class TestValidators(TestStdImage):
258
    def test_max_size_validator(self):
259
        self.client.post('/admin/tests/maxsizemodel/add/', {
260
            'image': self.fixtures['600x400.jpg'],
261
        })
262
        self.assertFalse(os.path.exists(os.path.join(IMG_DIR, 'image.jpg')))
263
264
    def test_min_size_validator(self):
265
        self.client.post('/admin/tests/minsizemodel/add/', {
266
            'image': self.fixtures['100.gif'],
267
        })
268
        self.assertFalse(os.path.exists(os.path.join(IMG_DIR, 'image.gif')))
269