Skip to content

Commit 6e7eca4

Browse files
authored
fix: issue with PhoneDevice being imported when not enabled
1 parent 08ef1b8 commit 6e7eca4

File tree

2 files changed

+72
-3
lines changed

2 files changed

+72
-3
lines changed

tests/test_views_profile.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from django.conf import settings
2+
from django.test import TestCase, override_settings
3+
from django.urls import reverse
4+
5+
from .utils import UserMixin
6+
7+
8+
class ProfileTest(UserMixin, TestCase):
9+
PHONENUMBER_PLUGIN_NAME = 'two_factor.plugins.phonenumber'
10+
EXPECTED_BASE_CONTEXT_KEYS = {
11+
'default_device',
12+
'default_device_type',
13+
'backup_tokens',
14+
}
15+
EXPECTED_PHONENUMBER_PLUGIN_ADDITIONAL_KEYS = {
16+
'backup_phones',
17+
'available_phone_methods',
18+
}
19+
20+
def setUp(self):
21+
super().setUp()
22+
self.user = self.create_user()
23+
self.enable_otp()
24+
self.login_user()
25+
26+
@classmethod
27+
def get_installed_apps_list(cls, with_phone_number_plugin=True):
28+
apps = set(settings.INSTALLED_APPS)
29+
if with_phone_number_plugin:
30+
apps.add(cls.PHONENUMBER_PLUGIN_NAME)
31+
else:
32+
apps.remove(cls.PHONENUMBER_PLUGIN_NAME)
33+
return list(apps)
34+
35+
def get_profile(self):
36+
url = reverse('two_factor:profile')
37+
return self.client.get(url)
38+
39+
def test_get_profile_without_phonenumer_plugin_enabled(self):
40+
apps_list = self.get_installed_apps_list(with_phone_number_plugin=False)
41+
with override_settings(INSTALLED_APPS=apps_list):
42+
response = self.get_profile()
43+
context_keys = set(response.context.keys())
44+
self.assertTrue(self.EXPECTED_BASE_CONTEXT_KEYS.issubset(context_keys))
45+
# None of the phonenumber related keys are present
46+
self.assertTrue(
47+
self.EXPECTED_PHONENUMBER_PLUGIN_ADDITIONAL_KEYS.isdisjoint(
48+
context_keys
49+
)
50+
)
51+
52+
def test_get_profile_with_phonenumer_plugin_enabled(self):
53+
apps_list = self.get_installed_apps_list(with_phone_number_plugin=True)
54+
with override_settings(INSTALLED_APPS=apps_list):
55+
response = self.get_profile()
56+
context_keys = set(response.context.keys())
57+
expected_keys = (
58+
self.EXPECTED_BASE_CONTEXT_KEYS
59+
| self.EXPECTED_PHONENUMBER_PLUGIN_ADDITIONAL_KEYS
60+
)
61+
self.assertTrue(expected_keys.issubset(context_keys))

two_factor/views/profile.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from django.apps.registry import apps
12
from django.conf import settings
23
from django.contrib.auth.decorators import login_required
34
from django.shortcuts import redirect, resolve_url
@@ -31,17 +32,24 @@ class ProfileView(TemplateView):
3132
def get_context_data(self, **kwargs):
3233
try:
3334
backup_tokens = self.request.user.staticdevice_set.all()[0].token_set.count()
35+
3436
except Exception:
3537
backup_tokens = 0
3638

37-
return {
39+
context = {
3840
'default_device': default_device(self.request.user),
3941
'default_device_type': default_device(self.request.user).__class__.__name__,
40-
'backup_phones': backup_phones(self.request.user),
4142
'backup_tokens': backup_tokens,
42-
'available_phone_methods': get_available_phone_methods()
4343
}
4444

45+
if (apps.is_installed('two_factor.plugins.phonenumber')):
46+
context.update({
47+
'backup_phones': backup_phones(self.request.user),
48+
'available_phone_methods': get_available_phone_methods(),
49+
})
50+
51+
return context
52+
4553

4654
@class_view_decorator(never_cache)
4755
class DisableView(FormView):

0 commit comments

Comments
 (0)