test_admin.py 17.6 KB
Newer Older
1
2
3
4
5
6
7
8
from unittest import mock
from unittest.mock import Mock

from django.contrib import messages
from django.contrib.admin import AdminSite
from django.contrib.admin.utils import model_ngettext
from django.http import HttpRequest
from django.test import SimpleTestCase, TestCase
9
from django.utils import timezone
10
11
12
from django.utils.translation import ugettext_lazy as _

from members.models import Member
13
from payments.models import Payment
14
from payments.widgets import PaymentWidget
15
from registrations import admin
16
from registrations.models import Entry, Registration, Renewal, Reference
17
18
19
20
21
22
23
24
25


def _get_mock_request(perms=None):
    if perms is None:
        perms = []

    mock_request = HttpRequest()
    mock_request.META = mock.Mock(return_value={})
    mock_request.user = mock.MagicMock()
26
    mock_request.user.pk = 1
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    mock_request.user.is_superuser = False
    mock_request.user.user_permissions = perms
    mock_request.user.has_perm = lambda x: x in perms
    mock_request._messages = mock.Mock()
    return mock_request


class GlobalAdminTest(SimpleTestCase):

    @mock.patch('registrations.admin.RegistrationAdmin')
    def test_show_message(self, admin_mock):
        admin_mock.return_value = admin_mock
        request = Mock(spec=HttpRequest)

        admin._show_message(admin_mock, request, 0, 'message', 'error')
        admin_mock.message_user.assert_called_once_with(
            request, 'error', messages.ERROR)
        admin_mock.message_user.reset_mock()
        admin._show_message(admin_mock, request, 1, 'message', 'error')
        admin_mock.message_user.assert_called_once_with(
            request, 'message', messages.SUCCESS)


class RegistrationAdminTest(TestCase):
51
    fixtures = ['members.json']
52
53
54
55
56
57
58
59
60
61
62
63
64

    def setUp(self):
        self.site = AdminSite()
        self.admin = admin.RegistrationAdmin(Registration,
                                             admin_site=self.site)

    @mock.patch('django.contrib.admin.ModelAdmin.changeform_view')
    @mock.patch('registrations.models.Entry.objects.get')
    def test_changeform_view(self, entry_get, super_method):
        request = _get_mock_request()
        object_id = None
        form_url = 'form://url'

65
66
67
68
69
        registration = Registration.objects.create(
            status=Entry.STATUS_REVIEW,
            birthday=timezone.now()
        )
        entry = registration.entry_ptr
70
71
72
73
74
        entry_get.return_value = entry

        self.admin.changeform_view(request, object_id, form_url)
        self.assertFalse(entry_get.called)
        super_method.assert_called_once_with(request, object_id, form_url, {
75
76
77
            'entry': None,
            'can_review': False,
            'can_resend': False,
78
            'can_revert': False,
79
80
81
        })

        super_method.reset_mock()
82
        entry_get.reset_mock()
83
84
85
86
87
        request = _get_mock_request(perms=['registrations.review_entries'])

        self.admin.changeform_view(request, object_id, form_url)
        self.assertFalse(entry_get.called)
        super_method.assert_called_once_with(request, object_id, form_url, {
88
89
90
            'entry': None,
            'can_review': False,
            'can_resend': False,
91
            'can_revert': False,
92
93
94
        })

        super_method.reset_mock()
95
96
        entry_get.reset_mock()
        object_id = entry.pk
97
98
99
100

        self.admin.changeform_view(request, object_id, form_url)
        self.assertTrue(entry_get.called)
        super_method.assert_called_once_with(request, object_id, form_url, {
101
102
103
            'entry': entry,
            'can_review': True,
            'can_resend': False,
104
            'can_revert': False,
105
106
107
        })

        super_method.reset_mock()
108
109
110
111
112
113
114
115
116
117
118
119
        entry_get.reset_mock()
        registration.status = Entry.STATUS_CONFIRM
        registration.save()
        entry = registration.entry_ptr
        entry_get.return_value = entry

        self.admin.changeform_view(request, object_id, form_url)
        self.assertTrue(entry_get.called)
        super_method.assert_called_once_with(request, object_id, form_url, {
            'entry': entry,
            'can_review': False,
            'can_resend': True,
120
            'can_revert': False,
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
        })

        super_method.reset_mock()
        entry_get.reset_mock()
        registration.status = Entry.STATUS_ACCEPTED
        registration.save()
        entry = registration.entry_ptr
        entry_get.return_value = entry

        self.admin.changeform_view(request, object_id, form_url)
        self.assertTrue(entry_get.called)
        super_method.assert_called_once_with(request, object_id, form_url, {
            'entry': entry,
            'can_review': False,
            'can_resend': False,
136
            'can_revert': True,
137
138
139
140
141
142
143
144
145
146
        })

        super_method.reset_mock()
        renewal = Renewal.objects.create(
            status=Entry.STATUS_REVIEW,
            member=Member.objects.filter(last_name="Wiggers").first()
        )
        entry = renewal.entry_ptr
        entry_get.return_value = entry
        object_id = entry.pk
147
148
149
150

        self.admin.changeform_view(request, object_id, form_url)
        self.assertTrue(entry_get.called)
        super_method.assert_called_once_with(request, object_id, form_url, {
151
152
153
            'entry': entry,
            'can_review': True,
            'can_resend': False,
154
            'can_revert': False,
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
        })

    @mock.patch('registrations.services.accept_entries')
    def test_accept(self, accept_entries):
        accept_entries.return_value = 1

        queryset = []

        request = _get_mock_request([])

        self.admin.accept_selected(request, queryset)
        accept_entries.assert_not_called()

        request = _get_mock_request(['registrations.review_entries'])
        self.admin.accept_selected(request, queryset)

171
        accept_entries.assert_called_once_with(1, queryset)
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

        request._messages.add.assert_called_once_with(
            messages.SUCCESS,
            _('Successfully accepted %(count)d %(items)s.')
            % {
                "count": 1,
                "items": model_ngettext(Registration(), 1)
            }, '')

    @mock.patch('registrations.services.reject_entries')
    def test_reject(self, reject_entries):
        reject_entries.return_value = 1

        queryset = []

        request = _get_mock_request([])

        self.admin.reject_selected(request, queryset)
        reject_entries.assert_not_called()

        request = _get_mock_request(['registrations.review_entries'])
        self.admin.reject_selected(request, queryset)
194
        reject_entries.assert_called_once_with(1, queryset)
195
196
197
198
199
200
201
202
203
204
205
206
207

        request._messages.add.assert_called_once_with(
            messages.SUCCESS,
            _('Successfully rejected %(count)d %(items)s.')
            % {
                "count": 1,
                "items": model_ngettext(Registration(), 1)
            }, '')

    def test_get_readonly_fields(self):
        request = _get_mock_request([])

        fields = self.admin.get_readonly_fields(request)
208
        self.assertEqual(fields, ['status', 'created_at',
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
209
                                  'updated_at'])
210
211
212
213

        fields = self.admin.get_readonly_fields(request, Registration(
            status=Entry.STATUS_CONFIRM
        ))
214
        self.assertEqual(fields, ['status', 'created_at', 'updated_at'])
215
216
217
218
219
220
221
222
223
224
225
226

        fields = self.admin.get_readonly_fields(request, Registration(
            status=Entry.STATUS_REJECTED
        ))
        self.assertCountEqual(fields, ['created_at', 'updated_at', 'status',
                                       'length', 'membership_type', 'remarks',
                                       'entry_ptr', 'username',
                                       'first_name', 'last_name',
                                       'birthday', 'language', 'email',
                                       'phone_number', 'student_number',
                                       'programme', 'starting_year',
                                       'address_street', 'address_street2',
227
                                       'address_postal_code', 'address_city',
228
                                       'address_country', 'membership',
229
230
                                       'optin_mailinglist', 'optin_birthday',
                                       'contribution'])
231
232
233
234
235
236
237
238
239
240
241
242

        fields = self.admin.get_readonly_fields(request, Registration(
            status=Entry.STATUS_ACCEPTED
        ))
        self.assertCountEqual(fields, ['created_at', 'updated_at', 'status',
                                       'length', 'membership_type', 'remarks',
                                       'entry_ptr', 'username',
                                       'first_name', 'last_name',
                                       'birthday', 'language', 'email',
                                       'phone_number', 'student_number',
                                       'programme', 'starting_year',
                                       'address_street', 'address_street2',
243
                                       'address_postal_code', 'address_city',
244
                                       'address_country', 'membership',
245
246
                                       'optin_mailinglist', 'optin_birthday',
                                       'contribution'])
247

248
249
250
251
252
253
254
255
256
257
258
259
        fields = self.admin.get_readonly_fields(request, Registration(
            status=Entry.STATUS_COMPLETED
        ))
        self.assertCountEqual(fields, ['created_at', 'updated_at', 'status',
                                       'length', 'membership_type', 'remarks',
                                       'entry_ptr', 'username',
                                       'first_name', 'last_name',
                                       'birthday', 'language', 'email',
                                       'phone_number', 'student_number',
                                       'programme', 'starting_year',
                                       'address_street', 'address_street2',
                                       'address_postal_code', 'address_city',
260
                                       'address_country', 'membership',
261
262
                                       'optin_mailinglist', 'optin_birthday',
                                       'contribution'])
263

264
    def test_get_actions(self):
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
265
266
        actions = self.admin.get_actions(_get_mock_request(
            ['registrations.delete_registration']))
267
268
269
        self.assertCountEqual(actions, ['delete_selected'])

        actions = self.admin.get_actions(
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
270
271
            _get_mock_request(['registrations.review_entries',
                               'registrations.delete_registration']))
272
273
274
275
276
277
278
279
280
281
        self.assertCountEqual(actions, ['delete_selected', 'accept_selected',
                                        'reject_selected'])

    def test_name(self):
        reg = Registration(
            first_name='John',
            last_name='Doe',
        )
        self.assertEqual(self.admin.name(reg), reg.get_full_name())

282
283
284
285
286
287
288
289
290
291
292
    def test_reference_count(self):
        reg = Registration.objects.create(
            first_name='John',
            last_name='Doe',
            birthday=timezone.now(),
        )
        self.assertEqual(self.admin.reference_count(reg), 0)
        Reference.objects.create(entry=reg, member=Member.objects.get(pk=1))
        Reference.objects.create(entry=reg, member=Member.objects.get(pk=2))
        self.assertEqual(self.admin.reference_count(reg), 2)

293
294
    def test_payment_status(self):
        reg = Registration(
295
            username='johnnytest',
296
297
298
299
300
301
302
303
            payment=Payment(
                pk='123',
            )
        )

        self.assertEqual(
            self.admin.payment_status(reg),
            '<a href="{}">{}</a>'.format(
304
                '/admin/payments/payment/123/change/',
305
306
                _('Unprocessed')))

307
        reg.payment.type = Payment.CARD
308
309
310
311

        self.assertEqual(
            self.admin.payment_status(reg),
            '<a href="{}">{}</a>'.format(
312
                '/admin/payments/payment/123/change/',
313
314
315
316
317
                _('Processed')))

        reg.payment = None
        self.assertEqual(self.admin.payment_status(reg), '-')

318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
    def test_formfield_for_dbfield(self):
        with self.subTest('Payment field'):
            field = self.admin.formfield_for_dbfield(
                Registration._meta.get_field('payment'), request=None)
            self.assertIsInstance(field.widget, PaymentWidget)
        with self.subTest('Other field'):
            field = self.admin.formfield_for_dbfield(
                Registration._meta.get_field('first_name'), request=None)
            self.assertNotIsInstance(field.widget, PaymentWidget)
            self.assertIsNotNone(field.widget)

    def test_save_model(self):
        reg = Registration(
            status=Registration.STATUS_REVIEW,
            birthday=timezone.now()
        )

        with self.subTest('Status review saves'):
            reg.first_name = 'Test1'
            self.admin.save_model({}, reg, None, True)
            self.assertTrue(
                Registration.objects.filter(first_name='Test1').exists())

        with self.subTest('Status accepted, no save'):
            reg.first_name = 'Test2'
            reg.status = Registration.STATUS_ACCEPTED
            self.admin.save_model({}, reg, None, True)
            self.assertFalse(
                Registration.objects.filter(first_name='Test2').exists())

        with self.subTest('Status reject, no save'):
            reg.first_name = 'Test2'
            reg.status = Registration.STATUS_REJECTED
            self.admin.save_model({}, reg, None, True)
            self.assertFalse(
                Registration.objects.filter(first_name='Test2').exists())

        with self.subTest('Status completed, no save'):
            reg.first_name = 'Test2'
            reg.status = Registration.STATUS_COMPLETED
            self.admin.save_model({}, reg, None, True)
            self.assertFalse(
                Registration.objects.filter(first_name='Test2').exists())

362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382

class RenewalAdminTest(TestCase):

    def setUp(self):
        self.site = AdminSite()
        self.admin = admin.RenewalAdmin(Renewal, admin_site=self.site)

    @mock.patch('registrations.services.accept_entries')
    def test_accept(self, accept_entries):
        accept_entries.return_value = 1

        queryset = []

        request = _get_mock_request([])

        self.admin.accept_selected(request, queryset)
        accept_entries.assert_not_called()

        request = _get_mock_request(['registrations.review_entries'])
        self.admin.accept_selected(request, queryset)

383
        accept_entries.assert_called_once_with(1, queryset)
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405

        request._messages.add.assert_called_once_with(
            messages.SUCCESS,
            _('Successfully accepted %(count)d %(items)s.')
            % {
                "count": 1,
                "items": model_ngettext(Renewal(), 1)
            }, '')

    @mock.patch('registrations.services.reject_entries')
    def test_reject(self, reject_entries):
        reject_entries.return_value = 1

        queryset = []

        request = _get_mock_request([])

        self.admin.reject_selected(request, queryset)
        reject_entries.assert_not_called()

        request = _get_mock_request(['registrations.review_entries'])
        self.admin.reject_selected(request, queryset)
406
        reject_entries.assert_called_once_with(1, queryset)
407
408
409
410
411
412
413
414
415
416
417
418
419

        request._messages.add.assert_called_once_with(
            messages.SUCCESS,
            _('Successfully rejected %(count)d %(items)s.')
            % {
                "count": 1,
                "items": model_ngettext(Renewal(), 1)
            }, '')

    def test_get_readonly_fields(self):
        request = _get_mock_request([])

        fields = self.admin.get_readonly_fields(request)
420
        self.assertEqual(fields, ['status', 'created_at',
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
421
                                  'updated_at'])
422
423
424
425
426

        fields = self.admin.get_readonly_fields(request, Renewal(
            status=Entry.STATUS_CONFIRM
        ))
        self.assertEqual(fields, ['status', 'created_at',
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
427
                                  'updated_at', 'member'])
428
429
430
431
432
433

        fields = self.admin.get_readonly_fields(request, Renewal(
            status=Entry.STATUS_REJECTED
        ))
        self.assertCountEqual(fields, ['created_at', 'updated_at', 'status',
                                       'length', 'membership_type', 'remarks',
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
434
                                       'entry_ptr', 'member',
435
                                       'membership', 'contribution'])
436
437
438
439
440
441

        fields = self.admin.get_readonly_fields(request, Renewal(
            status=Entry.STATUS_ACCEPTED
        ))
        self.assertCountEqual(fields, ['created_at', 'updated_at', 'status',
                                       'length', 'membership_type', 'remarks',
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
442
                                       'entry_ptr', 'member',
443
                                       'membership', 'contribution'])
444
445

    def test_get_actions(self):
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
446
447
        actions = self.admin.get_actions(_get_mock_request(
            ['registrations.delete_renewal']))
448
449
450
        self.assertCountEqual(actions, ['delete_selected'])

        actions = self.admin.get_actions(
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
451
452
            _get_mock_request(['registrations.delete_renewal',
                               'registrations.review_entries']))
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
        self.assertCountEqual(actions, ['delete_selected', 'accept_selected',
                                        'reject_selected'])

    def test_name(self):
        renewal = Renewal(
            member=Member(
                first_name='John',
                last_name="Doe",
            )
        )
        self.assertEqual(self.admin.name(renewal),
                         renewal.member.get_full_name())

    def test_email(self):
        renewal = Renewal(
            member=Member(
                email='test@example.org'
            )
        )
        self.assertEqual(self.admin.email(renewal),
                         'test@example.org')