Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6df19e3

Browse files
authored
Refactor how logged user navbar is constructed (python#1732)
* Refactor tests to use django testing tools instead of using mock* Create context processor to dinamically build user's navbar* Refactor base html to use backend data to organize the navbar
1 parent6d02143 commit6df19e3

File tree

4 files changed

+125
-33
lines changed

4 files changed

+125
-33
lines changed

‎pydotorg/context_processors.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
fromdjango.confimportsettings
2-
fromdjango.urlsimportresolve,Resolver404
2+
fromdjango.urlsimportresolve,Resolver404,reverse
33

44

55
defsite_info(request):
@@ -28,3 +28,38 @@ def blog_url(request):
2828
return {
2929
'BLOG_URL':settings.PYTHON_BLOG_URL,
3030
}
31+
32+
33+
defuser_nav_bar_links(request):
34+
nav= {}
35+
ifrequest.user.is_authenticated:
36+
user=request.user.username
37+
nav= {
38+
"account": {
39+
"label":"Your Account",
40+
"urls": [
41+
{"url":reverse("users:user_detail",args=[user]),"label":"View profile"},
42+
{"url":reverse("users:user_profile_edit"),"label":"Edit profile"},
43+
{"url":reverse("account_change_password"),"label":"Change password"},
44+
],
45+
},
46+
"psf_membership": {
47+
"label":"Membership",
48+
"urls": [
49+
{"url":reverse("users:user_nominations_view"),"label":"Nominations"},
50+
],
51+
}
52+
}
53+
54+
ifrequest.user.has_membership:
55+
nav["psf_membership"]['urls'].append({
56+
"url":reverse("users:user_membership_edit"),
57+
"label":"Edit PSF membership"
58+
})
59+
else:
60+
nav["psf_membership"]['urls'].append({
61+
"url":reverse("users:user_membership_create"),
62+
"label":"Become a PSF member"
63+
})
64+
65+
return {"USER_NAV_BAR":nav}

‎pydotorg/settings/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
'pydotorg.context_processors.url_name',
104104
'pydotorg.context_processors.get_host_with_scheme',
105105
'pydotorg.context_processors.blog_url',
106+
'pydotorg.context_processors.user_nav_bar_links',
106107
],
107108
},
108109
},
Lines changed: 80 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,93 @@
1+
frommodel_bakeryimportbaker
2+
3+
fromdjango.urlsimportreverse
14
fromdjango.confimportsettings
25
frompydotorgimportcontext_processors
3-
fromdjango.testimportTestCase
4-
5-
6-
classMockRequest:
7-
def__init__(self,path):
8-
self.path=path
9-
super().__init__()
6+
fromdjango.testimportTestCase,RequestFactory
7+
fromdjango.contrib.auth.modelsimportAnonymousUser
108

119

1210
classTemplateProcessorsTestCase(TestCase):
11+
defsetUp(self):
12+
self.factory=RequestFactory()
13+
1314
deftest_url_name(self):
14-
mock_request=MockRequest(path='/inner/')
15-
self.assertEqual({'URL_NAMESPACE':'','URL_NAME':'inner'},context_processors.url_name(mock_request))
15+
request=self.factory.get('/inner/')
16+
self.assertEqual({'URL_NAMESPACE':'','URL_NAME':'inner'},context_processors.url_name(request))
1617

17-
mock_request=MockRequest(path='/events/calendars/')
18-
self.assertEqual({'URL_NAMESPACE':'events','URL_NAME':'events:calendar_list'},context_processors.url_name(mock_request))
18+
request=self.factory.get('/events/calendars/')
19+
self.assertEqual({'URL_NAMESPACE':'events','URL_NAME':'events:calendar_list'},context_processors.url_name(request))
1920

20-
mock_request=MockRequest(path='/getit-404/releases/3.3.3/not-an-actual-thing/')
21-
self.assertEqual({},context_processors.url_name(mock_request))
21+
request=self.factory.get('/getit-404/releases/3.3.3/not-an-actual-thing/')
22+
self.assertEqual({},context_processors.url_name(request))
2223

23-
mock_request=MockRequest(path='/getit-404/releases/3.3.3/\r\n/')
24-
self.assertEqual({},context_processors.url_name(mock_request))
24+
request=self.factory.get('/getit-404/releases/3.3.3/\r\n/')
25+
self.assertEqual({},context_processors.url_name(request))
2526

26-
mock_request=MockRequest(path='/nothing/here/')
27-
self.assertEqual({},context_processors.url_name(mock_request))
27+
request=self.factory.get('/nothing/here/')
28+
self.assertEqual({},context_processors.url_name(request))
2829

2930
deftest_blog_url(self):
30-
mock_request=MockRequest(path='/about/')
31-
self.assertEqual({'BLOG_URL':settings.PYTHON_BLOG_URL},context_processors.blog_url(mock_request))
31+
request=self.factory.get('/about/')
32+
self.assertEqual({'BLOG_URL':settings.PYTHON_BLOG_URL},context_processors.blog_url(request))
33+
34+
deftest_user_nav_bar_links_for_non_psf_members(self):
35+
request=self.factory.get('/about/')
36+
request.user=baker.make(settings.AUTH_USER_MODEL,username='foo')
37+
38+
expected_nav= {
39+
"account": {
40+
"label":"Your Account",
41+
"urls": [
42+
{"url":reverse("users:user_detail",args=['foo']),"label":"View profile"},
43+
{"url":reverse("users:user_profile_edit"),"label":"Edit profile"},
44+
{"url":reverse("account_change_password"),"label":"Change password"},
45+
],
46+
},
47+
"psf_membership": {
48+
"label":"Membership",
49+
"urls": [
50+
{"url":reverse("users:user_nominations_view"),"label":"Nominations"},
51+
{"url":reverse("users:user_membership_create"),"label":"Become a PSF member"},
52+
],
53+
}
54+
}
55+
56+
self.assertEqual(
57+
{"USER_NAV_BAR":expected_nav},
58+
context_processors.user_nav_bar_links(request)
59+
)
60+
61+
deftest_user_nav_bar_links_for_psf_members(self):
62+
request=self.factory.get('/about/')
63+
request.user=baker.make(settings.AUTH_USER_MODEL,username='foo')
64+
baker.make('users.Membership',creator=request.user)
65+
66+
expected_nav= {
67+
"account": {
68+
"label":"Your Account",
69+
"urls": [
70+
{"url":reverse("users:user_detail",args=['foo']),"label":"View profile"},
71+
{"url":reverse("users:user_profile_edit"),"label":"Edit profile"},
72+
{"url":reverse("account_change_password"),"label":"Change password"},
73+
],
74+
},
75+
"psf_membership": {
76+
"label":"Membership",
77+
"urls": [
78+
{"url":reverse("users:user_nominations_view"),"label":"Nominations"},
79+
{"url":reverse("users:user_membership_edit"),"label":"Edit PSF membership"},
80+
],
81+
}
82+
}
83+
84+
self.assertEqual(
85+
{"USER_NAV_BAR":expected_nav},
86+
context_processors.user_nav_bar_links(request)
87+
)
88+
89+
deftest_user_nav_bar_links_for_anonymous_user(self):
90+
request=self.factory.get('/about/')
91+
request.user=AnonymousUser()
3292

93+
self.assertEqual({"USER_NAV_BAR": {}},context_processors.user_nav_bar_links(request))

‎templates/users/base.html

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,18 @@
1414

1515

1616
{% block content %}
17-
18-
{% if request.user.is_authenticated %}
17+
{% if USER_NAV_BAR %}
1918
<divclass="user-profile-controls">
2019
<ulclass="menu">
21-
<li>Manage your Information:</li>
22-
<li><ahref="{% url 'users:user_detail' slug=request.user.username %}">View profile</a></li>
23-
<li><ahref="{% url 'users:user_nominations_view' %}">Nominations</a></li>
24-
<li><ahref="{% url 'users:user_profile_edit' %}">Edit profile</a></li>
25-
{% if request.user.has_membership %}
26-
<li><ahref="{% url 'users:user_membership_edit' %}">Edit PSF membership</a></li>
27-
{% else %}
28-
<li><ahref="{% url 'users:user_membership_create' %}">Become a PSF member</a></li>
29-
{% endif %}
30-
<li><ahref="{% url 'account_change_password' %}">Change Password</a></li>
20+
<li>Manage your Information:</li>
21+
{% for section in USER_NAV_BAR.values %}
22+
{% for url in section.urls %}
23+
<li><ahref="{{ url.url }}">{{ url.label }}</a></li>
24+
{% endfor %}
25+
{% endfor %}
3126
</ul>
3227
</div>
33-
{% endif %}
3428
{% block user_content %}{% endblock %}
29+
{% endif %}
3530

3631
{% endblock %}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp