Passed
Push — master ( 69cc74...79e85a )
by Alexander
02:36
created

TestRegistration.test_only_one_superuser()   A

Complexity

Conditions 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 11
rs 10
c 0
b 0
f 0
cc 1
nop 1
1
# -*- coding: utf-8 -*-
2
# pylint: disable=invalid-name
3
4
import datetime
5
6
from django.conf import settings
7
from django.contrib.auth import get_user_model
8
from django.contrib.sites.models import Site
9
from django.test import TestCase, override_settings
10
from django.urls import reverse
11
from django.utils import timezone
12
from django.utils.translation import gettext_lazy as _
13
from mock import patch
14
15
from tcms import signals
16
from tcms.kiwi_auth import forms
17
from tcms.kiwi_auth.models import UserActivationKey
18
from tcms.tests.factories import UserFactory
19
20
User = get_user_model()  # pylint: disable=invalid-name
21
22
23
class TestSetRandomKey(TestCase):
24
    """Test case for UserActivationKey.set_random_key_for_user"""
25
26
    @classmethod
27
    def setUpTestData(cls):
28
        cls.new_user = UserFactory()
29
30
    @patch("tcms.kiwi_auth.models.datetime")
31
    def test_set_random_key(self, mock_datetime):
32
        now = timezone.now()
33
        in_7_days = datetime.timedelta(7)
34
35
        mock_datetime.datetime.today.return_value = now
36
        mock_datetime.timedelta.return_value = in_7_days
37
38
        activation_key = UserActivationKey.set_random_key_for_user(self.new_user)
39
        self.assertEqual(self.new_user, activation_key.user)
40
        self.assertNotEqual("", activation_key.activation_key)
41
        self.assertEqual(now + in_7_days, activation_key.key_expires)
42
43
44
class TestForceToSetRandomKey(TestCase):
45
    """Test case for UserActivationKey.set_random_key_for_user forcely"""
46
47
    @classmethod
48
    def setUpTestData(cls):
49
        cls.new_user = UserFactory()
50
        cls.origin_activation_key = UserActivationKey.set_random_key_for_user(
51
            cls.new_user
52
        )
53
54
    def test_set_random_key_forcely(self):
55
        new_activation_key = UserActivationKey.set_random_key_for_user(
56
            self.new_user, force=True
57
        )
58
        self.assertEqual(self.origin_activation_key.user, new_activation_key.user)
59
        self.assertNotEqual(
60
            self.origin_activation_key.activation_key, new_activation_key.activation_key
61
        )
62
63
64
# ### Test cases for view methods ###
65
66
67
class TestLogout(TestCase):
68
    """Test for logout view method"""
69
70
    @classmethod
71
    def setUpTestData(cls):
72
        super(TestLogout, cls).setUpTestData()
73
74
        cls.tester = UserFactory()
75
        cls.tester.set_password("password")
76
        cls.tester.save()
77
        cls.logout_url = reverse("tcms-logout")
78
79
    def test_logout_redirects_to_login_page(self):
80
        self.client.login(  # nosec:B106:hardcoded_password_funcarg
81
            username=self.tester.username, password="password"
82
        )
83
        response = self.client.get(self.logout_url, follow=True)
84
        self.assertRedirects(response, reverse("tcms-login"))
85
86
    def test_logout_then_goto_next(self):
87
        self.client.login(  # nosec:B106:hardcoded_password_funcarg
88
            username=self.tester.username, password="password"
89
        )
90
        next_url = reverse("tcms-login") + "?next=" + reverse("plans-search")
91
        response = self.client.get(self.logout_url, {"next": next_url}, follow=True)
92
        self.assertRedirects(response, next_url)
93
94
95
class TestRegistration(TestCase):
96
    def setUp(self):
97
        self.register_url = reverse("tcms-register")
98
        self.fake_activate_key = "secret-activate-key"
99
100
    def test_open_registration_page(self):
101
        response = self.client.get(self.register_url)
102
        self.assertContains(response, ">%s</button>" % _("Register"))
103
104
    def assert_user_registration(self, username, follow=False):
105
106
        with patch("tcms.kiwi_auth.models.secrets") as _secrets:
107
            _secrets.token_hex.return_value = self.fake_activate_key
108
109
            response = self.client.post(
110
                self.register_url,
111
                {
112
                    "username": username,
113
                    "password1": "password",
114
                    "password2": "password",
115
                    "email": "[email protected]",
116
                },
117
                follow=follow,
118
            )
119
120
        user = User.objects.get(username=username)
121
        self.assertEqual("[email protected]", user.email)
122
        self.assertFalse(user.is_active)
123
124
        key = UserActivationKey.objects.get(user=user)
125
        self.assertEqual(self.fake_activate_key, key.activation_key)
126
127
        return response, user
128
129
    @patch("tcms.signals.USER_REGISTERED_SIGNAL.send")
130
    def test_register_user_sends_signal(self, signal_mock):
131
        self.assert_user_registration("new-signal-tester")
132
        self.assertTrue(signal_mock.called)
133
        self.assertEqual(1, signal_mock.call_count)
134
135
    @override_settings(ADMINS=[("Test Admin", "[email protected]")])
136
    @patch("tcms.core.utils.mailto.send_mail")
137
    def test_signal_handler_notifies_admins(self, send_mail):
138
        # connect the handler b/c it is not connected by default
139
        signals.USER_REGISTERED_SIGNAL.connect(signals.notify_admins)
140
141
        try:
142
            response, user = self.assert_user_registration("signal-handler")
143
            self.assertRedirects(
144
                response, reverse("core-views-index"), target_status_code=302
145
            )
146
147
            # 1 - verification mail, 2 - email to admin
148
            self.assertTrue(send_mail.called)
149
            self.assertEqual(2, send_mail.call_count)
150
151
            # verify we've actually sent the admin email
152
            self.assertIn(
153
                str(_("New user awaiting approval")), send_mail.call_args_list[0][0][0]
154
            )
155
            values = {
156
                "username": "signal-handler",
157
                "user_url": "http://testserver/admin/auth/user/%d/change/" % user.pk,
158
            }
159
            expected = (
160
                _(
161
                    """Dear Administrator,
162
somebody just registered an account with username %(username)s at your
163
Kiwi TCMS instance and is awaiting your approval!
164
165
Go to %(user_url)s to activate the account!"""
166
                )
167
                % values
168
            )
169
            self.assertEqual(
170
                expected.strip(), send_mail.call_args_list[0][0][1].strip()
171
            )
172
            self.assertIn("[email protected]", send_mail.call_args_list[0][0][-1])
173
        finally:
174
            signals.USER_REGISTERED_SIGNAL.disconnect(signals.notify_admins)
175
176
    @patch("tcms.core.utils.mailto.send_mail")
177
    def test_register_user_by_email_confirmation(self, send_mail):
178
        response, user = self.assert_user_registration("new-tester", follow=True)
179
        self.assertContains(
180
            response,
181
            _(
182
                "Your account has been created, please check your mailbox for confirmation"
183
            ),
184
        )
185
186
        site = Site.objects.get(pk=settings.SITE_ID)
187
        confirm_url = "http://%s%s" % (
188
            site.domain,
189
            reverse("tcms-confirm", args=[self.fake_activate_key]),
190
        )
191
192
        # Verify notification mail
193
        values = {
194
            "user": user.username,
195
            "site_domain": site.domain,
196
            "confirm_url": confirm_url,
197
        }
198
        expected_subject = (
199
            settings.EMAIL_SUBJECT_PREFIX
200
            + _("Your new %s account confirmation") % site.domain
201
        )
202
        expected_body = (
203
            _(
204
                """Welcome %(user)s,
205
thank you for signing up for an %(site_domain)s account!
206
207
To activate your account, click this link:
208
%(confirm_url)s"""
209
            )
210
            % values
211
            + "\n"
212
        )
213
        send_mail.assert_called_once_with(
214
            expected_subject,
215
            expected_body,
216
            settings.DEFAULT_FROM_EMAIL,
217
            ["[email protected]"],
218
            fail_silently=False,
219
        )
220
221
    @override_settings(
222
        AUTO_APPROVE_NEW_USERS=False,
223
        ADMINS=[("admin1", "[email protected]"), ("admin2", "[email protected]")],
224
    )
225
    def test_register_user_and_activate_by_admin(self):
226
        response, _user = self.assert_user_registration("plan-tester", follow=True)
227
228
        self.assertContains(
229
            response,
230
            _(
231
                "Your account has been created, but you need an administrator to activate it"
232
            ),
233
        )
234
235
        for (name, email) in settings.ADMINS:
236
            self.assertContains(
237
                response, '<a href="mailto:{}">{}</a>'.format(email, name), html=True
238
            )
239
240
    def test_invalid_form(self):
241
        response = self.client.post(
242
            self.register_url,
243
            {
244
                "username": "kiwi-tester",
245
                "password1": "password-1",
246
                "password2": "password-2",
247
                "email": "[email protected]",
248
            },
249
            follow=False,
250
        )
251
252
        self.assertContains(response, _("The two password fields didn’t match."))
253
        self.assertEqual(response.status_code, 200)
254
        self.assertTemplateUsed(response, "registration/registration_form.html")
255
256
    def test_register_user_already_registered(self):
257
        User.objects.create_user("kiwi-tester", "[email protected]", "password")
258
259
        response = self.client.post(
260
            self.register_url,
261
            {
262
                "username": "test_user",
263
                "password1": "password",
264
                "password2": "password",
265
                "email": "[email protected]",
266
            },
267
            follow=False,
268
        )
269
        self.assertContains(response, _("A user with that email already exists."))
270
271
        user = User.objects.filter(username="test_user")
272
        self.assertEqual(user.count(), 0)
273
274
    def test_first_user_is_superuser(self):
275
        response, _user = self.assert_user_registration("tester_1")
276
277
        self.assertTrue(_user.is_superuser)
278
279
    def test_only_one_superuser(self):
280
        user1 = User.objects.create_user(
281
            "kiwi-tester", "[email protected]", "password"
282
        )
283
        user1.is_superuser = True
284
        user1.save()
285
286
        self.assertTrue(user1.is_superuser)
287
288
        response, user2 = self.assert_user_registration("plan-tester")
289
        self.assertFalse(user2.is_superuser)
290
291
292
class TestConfirm(TestCase):
293
    """Test for activation key confirmation"""
294
295
    @classmethod
296
    def setUpTestData(cls):
297
        cls.new_user = UserFactory()
298
299
    def setUp(self):
300
        self.new_user.is_active = False
301
        self.new_user.save()
302
303
    def test_fail_if_activation_key_does_not_exist(self):
304
        confirm_url = reverse("tcms-confirm", args=["nonexisting-activation-key"])
305
        response = self.client.get(confirm_url, follow=True)
306
307
        self.assertContains(
308
            response, _("This activation key no longer exists in the database")
309
        )
310
311
        # user account not activated
312
        user = User.objects.get(username=self.new_user.username)
313
        self.assertFalse(user.is_active)
314
315
    def test_fail_if_activation_key_expired(self):
316
        fake_activation_key = "secret-activation-key"
317
318
        with patch("tcms.kiwi_auth.models.secrets") as _secrets:
319
            _secrets.token_hex.return_value = fake_activation_key
320
            key = UserActivationKey.set_random_key_for_user(self.new_user)
321
            key.key_expires = timezone.now() - datetime.timedelta(days=10)
322
            key.save()
323
324
        confirm_url = reverse("tcms-confirm", args=[fake_activation_key])
325
        response = self.client.get(confirm_url, follow=True)
326
327
        self.assertContains(response, _("This activation key has expired"))
328
329
        # user account not activated
330
        user = User.objects.get(username=self.new_user.username)
331
        self.assertFalse(user.is_active)
332
333
    def test_confirm(self):
334
        fake_activate_key = "secret-activate-key"
335
336
        with patch("tcms.kiwi_auth.models.secrets") as _secrets:
337
            _secrets.token_hex.return_value = fake_activate_key
338
            UserActivationKey.set_random_key_for_user(self.new_user)
339
340
        confirm_url = reverse("tcms-confirm", args=[fake_activate_key])
341
        response = self.client.get(confirm_url, follow=True)
342
343
        self.assertContains(response, _("Your account has been activated successfully"))
344
345
        # user account activated
346
        user = User.objects.get(username=self.new_user.username)
347
        self.assertTrue(user.is_active)
348
        activate_key_deleted = not UserActivationKey.objects.filter(user=user).exists()
349
        self.assertTrue(activate_key_deleted)
350
351
352
class TestLoginViewWithCustomTemplate(TestCase):
353
    """Test for login view with custom template"""
354
355
    def test_get_template_names(self):
356
        response = self.client.get(reverse("tcms-login"))
357
        self.assertIsNotNone(response.template_name)
358
        self.assertEqual(
359
            response.template_name,
360
            ["registration/custom_login.html", "registration/login.html"],
361
        )
362
363
364
class TestPasswordResetView(TestCase):
365
    """Test for password reset view"""
366
367
    def setUp(self):
368
        self.password_reset_url = reverse("tcms-password_reset")
369
370
    def test_form_class(self):
371
        response = self.client.get(self.password_reset_url)
372
        self.assertEqual(
373
            str(type(response.context["form"])),
374
            str(forms.PasswordResetForm),
375
        )
376
377
    def test_open_password_reset_page(self):
378
        response = self.client.get(self.password_reset_url)
379
380
        self.assertContains(response, ">%s</button>" % _("Password reset"))
381
382
    @patch("tcms.kiwi_auth.forms.DjangoPasswordResetForm.send_mail")
383
    def test_send_mail_for_password_reset(self, mail_sent):
384
        user = User.objects.create_user("kiwi-tester", "[email protected]", "password")
385
        user.is_active = True
386
        user.save()
387
        data = {"email": "[email protected]"}
388
        response = self.client.post(self.password_reset_url, data, follow=True)
389
390
        self.assertContains(response, _("Password reset email was sent"))
391
392
        # Verify mail is sent
393
        mail_sent.assert_called_once()
394