Skip to content

Commit 6d1e44b

Browse files
JacobCoffeeclaude
andcommitted
update tests: use absolute imports and Fellow model
Replace relative dot imports with absolute `nominations.tests.factories` imports. Migrate test assertions from Membership to Fellow model. Fix nomination_statement min-length in test data. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 9581f6d commit 6d1e44b

6 files changed

Lines changed: 72 additions & 127 deletions

File tree

nominations/tests/test_forms.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from nominations.forms import FellowNominationForm
66
from nominations.models import FellowNominationRound
7-
from .factories import UserFactory, FellowNominationRoundFactory
7+
from nominations.tests.factories import UserFactory, FellowNominationRoundFactory
88

99

1010
class FellowNominationFormTests(TestCase):
@@ -19,7 +19,7 @@ def test_valid_form(self):
1919
data = {
2020
"nominee_name": "Jane Doe",
2121
"nominee_email": "jane@example.com",
22-
"nomination_statement": "Great contributor to Python.",
22+
"nomination_statement": "Jane has made outstanding contributions to the Python community through years of dedicated work on documentation, mentoring, and conference organization.",
2323
"nomination_statement_markup_type": "markdown",
2424
}
2525
form = FellowNominationForm(data=data, request=self.request)

nominations/tests/test_management_views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from django.contrib.auth.models import Group
66

77
from nominations.models import FellowNomination, FellowNominationRound
8-
from .factories import (
8+
from nominations.tests.factories import (
99
UserFactory,
1010
FellowNominationRoundFactory,
1111
FellowNominationFactory,

nominations/tests/test_models.py

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44
from django.test import TestCase
55
from django.utils import timezone
66

7-
from users.models import Membership
8-
97
from nominations.models import (
8+
Fellow,
109
FellowNominationRound,
1110
FellowNomination,
1211
FellowNominationVote,
1312
)
14-
from .factories import (
13+
from nominations.tests.factories import (
1514
UserFactory,
1615
FellowNominationRoundFactory,
1716
FellowNominationFactory,
@@ -153,35 +152,21 @@ def test_nominee_is_already_fellow_false_no_user(self):
153152
self.nomination.nominee_user = None
154153
self.assertFalse(self.nomination.nominee_is_already_fellow)
155154

156-
def test_nominee_is_already_fellow_false_no_membership(self):
155+
def test_nominee_is_already_fellow_false_no_fellow_record(self):
157156
nominee_user = UserFactory()
158157
self.nomination.nominee_user = nominee_user
159158
self.assertFalse(self.nomination.nominee_is_already_fellow)
160159

161160
def test_nominee_is_already_fellow_true(self):
162161
nominee_user = UserFactory()
163-
Membership.objects.create(
164-
creator=nominee_user,
165-
membership_type=Membership.FELLOW,
166-
legal_name="Test Fellow",
167-
preferred_name="Test",
168-
email_address=nominee_user.email,
162+
Fellow.objects.create(
163+
name="Test Fellow",
164+
year_elected=2020,
165+
user=nominee_user,
169166
)
170167
self.nomination.nominee_user = nominee_user
171168
self.assertTrue(self.nomination.nominee_is_already_fellow)
172169

173-
def test_nominee_is_already_fellow_false_basic_member(self):
174-
nominee_user = UserFactory()
175-
Membership.objects.create(
176-
creator=nominee_user,
177-
membership_type=Membership.BASIC,
178-
legal_name="Test Basic",
179-
preferred_name="Test",
180-
email_address=nominee_user.email,
181-
)
182-
self.nomination.nominee_user = nominee_user
183-
self.assertFalse(self.nomination.nominee_is_already_fellow)
184-
185170

186171
class FellowNominationVoteResultTests(TestCase):
187172
def setUp(self):

nominations/tests/test_review_views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from django.contrib.auth.models import Group
88

99
from nominations.models import FellowNomination, FellowNominationVote
10-
from .factories import (
10+
from nominations.tests.factories import (
1111
UserFactory,
1212
FellowNominationRoundFactory,
1313
FellowNominationFactory,
Lines changed: 53 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
from django.test import TestCase, Client
22
from django.urls import reverse
33

4-
from users.models import Membership
5-
6-
from .factories import UserFactory
4+
from nominations.models import Fellow
75

86

97
class FellowsRosterViewTests(TestCase):
@@ -23,62 +21,18 @@ def test_alt_url_works(self):
2321
self.assertEqual(response.status_code, 200)
2422

2523
def test_only_fellows_shown(self):
26-
"""Only members with membership_type=FELLOW should appear on the roster."""
27-
fellow_user = UserFactory(first_name="Alice", last_name="Fellow")
28-
Membership.objects.create(
29-
creator=fellow_user,
30-
membership_type=Membership.FELLOW,
31-
legal_name="Alice Fellow",
32-
preferred_name="Alice",
33-
email_address=fellow_user.email,
34-
)
35-
basic_user = UserFactory(first_name="Bob", last_name="Basic")
36-
Membership.objects.create(
37-
creator=basic_user,
38-
membership_type=Membership.BASIC,
39-
legal_name="Bob Basic",
40-
preferred_name="Bob",
41-
email_address=basic_user.email,
42-
)
43-
supporting_user = UserFactory(first_name="Carol", last_name="Supporter")
44-
Membership.objects.create(
45-
creator=supporting_user,
46-
membership_type=Membership.SUPPORTING,
47-
legal_name="Carol Supporter",
48-
preferred_name="Carol",
49-
email_address=supporting_user.email,
50-
)
24+
"""All Fellow records should appear on the roster."""
25+
Fellow.objects.create(name="Alice Fellow", year_elected=2020, status="active")
26+
Fellow.objects.create(name="Bob Emeritus", year_elected=2015, status="emeritus")
5127
response = self.client.get(self.url)
5228
self.assertContains(response, "Alice Fellow")
53-
self.assertNotContains(response, "Bob Basic")
54-
self.assertNotContains(response, "Carol Supporter")
29+
self.assertContains(response, "Bob Emeritus")
5530

5631
def test_alphabetical_ordering(self):
57-
"""Fellows should be ordered by last name, then first name."""
58-
user_z = UserFactory(first_name="Zara", last_name="Zebra")
59-
Membership.objects.create(
60-
creator=user_z,
61-
membership_type=Membership.FELLOW,
62-
legal_name="Zara Zebra",
63-
preferred_name="Zara",
64-
email_address=user_z.email,
65-
)
66-
user_a = UserFactory(first_name="Alice", last_name="Alpha")
67-
Membership.objects.create(
68-
creator=user_a,
69-
membership_type=Membership.FELLOW,
70-
legal_name="Alice Alpha",
71-
preferred_name="Alice",
72-
email_address=user_a.email,
73-
)
74-
user_m = UserFactory(first_name="Mike", last_name="Middle")
75-
Membership.objects.create(
76-
creator=user_m,
77-
membership_type=Membership.FELLOW,
78-
legal_name="Mike Middle",
79-
preferred_name="Mike",
80-
email_address=user_m.email,
81-
)
32+
"""Fellows should be ordered by name."""
33+
Fellow.objects.create(name="Zara Zebra", year_elected=2020, status="active")
34+
Fellow.objects.create(name="Alice Alpha", year_elected=2019, status="active")
35+
Fellow.objects.create(name="Mike Middle", year_elected=2018, status="active")
8236
response = self.client.get(self.url)
8337
content = response.content.decode()
8438
pos_alice = content.index("Alice Alpha")
@@ -90,52 +44,62 @@ def test_alphabetical_ordering(self):
9044
def test_total_count_in_context(self):
9145
"""The context should include the total count of Fellows."""
9246
for i in range(3):
93-
user = UserFactory(first_name=f"Fellow{i}", last_name=f"User{i}")
94-
Membership.objects.create(
95-
creator=user,
96-
membership_type=Membership.FELLOW,
97-
legal_name=f"Fellow{i} User{i}",
98-
preferred_name=f"Fellow{i}",
99-
email_address=user.email,
47+
Fellow.objects.create(
48+
name=f"Fellow{i} User{i}", year_elected=2020, status="active"
10049
)
10150
response = self.client.get(self.url)
10251
self.assertEqual(response.context["total_count"], 3)
103-
self.assertContains(response, "3")
10452

10553
def test_empty_roster(self):
10654
"""When there are no Fellows, an appropriate message should be shown."""
10755
response = self.client.get(self.url)
10856
self.assertEqual(response.status_code, 200)
10957
self.assertContains(response, "No PSF Fellows found")
11058

111-
def test_fellow_with_location(self):
112-
"""Fellow with city and country should display location info."""
113-
user = UserFactory(first_name="Located", last_name="Fellow")
114-
Membership.objects.create(
115-
creator=user,
116-
membership_type=Membership.FELLOW,
117-
legal_name="Located Fellow",
118-
preferred_name="Located",
119-
email_address=user.email,
120-
city="Portland",
121-
country="USA",
59+
def test_year_displayed(self):
60+
"""Fellow year elected should be displayed in parentheses."""
61+
Fellow.objects.create(name="Year Fellow", year_elected=2019, status="active")
62+
response = self.client.get(self.url)
63+
self.assertContains(response, "Year Fellow (2019)")
64+
65+
def test_emeritus_year_displayed(self):
66+
"""Emeritus fellows should show both elected and emeritus year."""
67+
Fellow.objects.create(
68+
name="Old Fellow", year_elected=2005, status="emeritus", emeritus_year=2020
12269
)
12370
response = self.client.get(self.url)
124-
self.assertContains(response, "Portland")
125-
self.assertContains(response, "USA")
71+
self.assertContains(response, "Old Fellow (2005/2020)")
12672

127-
def test_fellow_without_location(self):
128-
"""Fellow without city/country should still render without errors."""
129-
user = UserFactory(first_name="NoLoc", last_name="Fellow")
130-
Membership.objects.create(
131-
creator=user,
132-
membership_type=Membership.FELLOW,
133-
legal_name="NoLoc Fellow",
134-
preferred_name="NoLoc",
135-
email_address=user.email,
136-
city="",
137-
country="",
73+
def test_deceased_notes_displayed(self):
74+
"""Deceased fellows should show notes if present."""
75+
Fellow.objects.create(
76+
name="Remembered Fellow",
77+
year_elected=2010,
78+
status="deceased",
79+
notes="A great contributor.",
13880
)
13981
response = self.client.get(self.url)
140-
self.assertEqual(response.status_code, 200)
141-
self.assertContains(response, "NoLoc Fellow")
82+
self.assertContains(response, "Remembered Fellow")
83+
self.assertContains(response, "A great contributor.")
84+
85+
def test_sections_in_context(self):
86+
"""Context should include separate querysets for each status."""
87+
Fellow.objects.create(name="Active One", year_elected=2020, status="active")
88+
Fellow.objects.create(name="Active Two", year_elected=2019, status="active")
89+
Fellow.objects.create(name="Emeritus One", year_elected=2010, status="emeritus")
90+
Fellow.objects.create(name="Deceased One", year_elected=2005, status="deceased")
91+
response = self.client.get(self.url)
92+
self.assertEqual(response.context["active_count"], 2)
93+
self.assertEqual(response.context["emeritus_count"], 1)
94+
self.assertEqual(response.context["deceased_count"], 1)
95+
self.assertEqual(response.context["total_count"], 4)
96+
97+
def test_section_headings_rendered(self):
98+
"""Each section heading should appear when fellows of that status exist."""
99+
Fellow.objects.create(name="Active Fellow", year_elected=2020, status="active")
100+
Fellow.objects.create(name="Emeritus Fellow", year_elected=2010, status="emeritus")
101+
Fellow.objects.create(name="Deceased Fellow", year_elected=2005, status="deceased")
102+
response = self.client.get(self.url)
103+
self.assertContains(response, "Fellows (1)")
104+
self.assertContains(response, "Emeritus Fellows (1)")
105+
self.assertContains(response, "In Memoriam (1)")

nominations/tests/test_views.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
from django.utils import timezone
77
from django.contrib.auth.models import Group
88

9-
from users.models import Membership
10-
11-
from nominations.models import FellowNomination, FellowNominationRound
12-
from .factories import (
9+
from nominations.models import Fellow, FellowNomination, FellowNominationRound
10+
from nominations.tests.factories import (
1311
UserFactory,
1412
FellowNominationRoundFactory,
1513
FellowNominationFactory,
@@ -58,7 +56,7 @@ def test_successful_submission(self, mock_now, mock_wg_notify, mock_nominator_no
5856
data = {
5957
"nominee_name": "Jane Doe",
6058
"nominee_email": "jane@example.com",
61-
"nomination_statement": "Great contributions.",
59+
"nomination_statement": "Jane has made outstanding contributions to the Python community through years of dedicated work on documentation, mentoring, and conference organization.",
6260
"nomination_statement_markup_type": "markdown",
6361
}
6462
response = self.client.post(self.url, data)
@@ -76,17 +74,15 @@ def test_fellow_warning_shown(self, mock_now, mock_wg_notify, mock_nominator_not
7674
datetime.datetime(2026, 1, 15, 12, 0)
7775
)
7876
fellow_user = UserFactory(email="fellow@example.com")
79-
Membership.objects.create(
80-
creator=fellow_user,
81-
membership_type=Membership.FELLOW,
82-
legal_name="Fellow User",
83-
preferred_name="Fellow",
84-
email_address="fellow@example.com",
77+
Fellow.objects.create(
78+
name="Fellow User",
79+
year_elected=2020,
80+
user=fellow_user,
8581
)
8682
data = {
8783
"nominee_name": "Fellow User",
8884
"nominee_email": "fellow@example.com",
89-
"nomination_statement": "Already a fellow.",
85+
"nomination_statement": "This person has been an incredible contributor to the Python community through years of sustained effort across multiple projects and initiatives.",
9086
"nomination_statement_markup_type": "markdown",
9187
}
9288
response = self.client.post(self.url, data, follow=True)

0 commit comments

Comments
 (0)