@@ -173,6 +173,74 @@ def test_flags_incomplete_project(self):
173173 self .assertIn ("no publication" , rows ["Lonely Project" ]["issues" ])
174174
175175
176+ class ProjectLeadershipCheckTests (DatabaseTestCase ):
177+ def _add_role (self , project , lead_role , start_date , end_date = None ):
178+ from website .models import ProjectRole
179+
180+ person = self .make_person (first_name = "Lead" , last_name = "Person" )
181+ return ProjectRole .objects .create (
182+ person = person ,
183+ project = project ,
184+ lead_project_role = lead_role ,
185+ start_date = start_date ,
186+ end_date = end_date ,
187+ )
188+
189+ def test_flags_project_with_no_pi (self ):
190+ proj = self .make_project (name = "PI-less Project" )
191+ rows = {r ["name" ]: r for r in get_check ("project-leadership" ).get_rows ()}
192+ self .assertIn ("PI-less Project" , rows )
193+ self .assertEqual (rows ["PI-less Project" ]["issues" ], "no PI" )
194+ self .assertEqual (rows ["PI-less Project" ]["pi_count" ], 0 )
195+
196+ def test_ongoing_project_with_only_an_ended_pi_flagged_no_active_pi (self ):
197+ from datetime import date , timedelta
198+ from website .models .project_role import LeadProjectRoleTypes
199+
200+ proj = self .make_project (name = "Stale Lead Project" ) # no end_date => ongoing
201+ self ._add_role (
202+ proj ,
203+ LeadProjectRoleTypes .PI ,
204+ start_date = date .today () - timedelta (days = 400 ),
205+ end_date = date .today () - timedelta (days = 30 ),
206+ )
207+ rows = {r ["name" ]: r for r in get_check ("project-leadership" ).get_rows ()}
208+ self .assertIn ("Stale Lead Project" , rows )
209+ self .assertEqual (rows ["Stale Lead Project" ]["issues" ], "no active PI" )
210+ self .assertEqual (rows ["Stale Lead Project" ]["pi_count" ], 1 )
211+ self .assertEqual (rows ["Stale Lead Project" ]["active_pi_count" ], 0 )
212+
213+ def test_project_with_active_pi_not_flagged (self ):
214+ from datetime import date , timedelta
215+ from website .models .project_role import LeadProjectRoleTypes
216+
217+ proj = self .make_project (name = "Well-Led Project" )
218+ self ._add_role (
219+ proj ,
220+ LeadProjectRoleTypes .PI ,
221+ start_date = date .today () - timedelta (days = 30 ),
222+ )
223+ names = {r ["name" ] for r in get_check ("project-leadership" ).get_rows ()}
224+ self .assertNotIn ("Well-Led Project" , names )
225+
226+ def test_ended_project_with_ended_pi_not_flagged (self ):
227+ from datetime import date , timedelta
228+ from website .models .project_role import LeadProjectRoleTypes
229+
230+ proj = self .make_project (
231+ name = "Wrapped-Up Project" ,
232+ end_date = date .today () - timedelta (days = 10 ),
233+ )
234+ self ._add_role (
235+ proj ,
236+ LeadProjectRoleTypes .PI ,
237+ start_date = date .today () - timedelta (days = 400 ),
238+ end_date = date .today () - timedelta (days = 20 ),
239+ )
240+ names = {r ["name" ] for r in get_check ("project-leadership" ).get_rows ()}
241+ self .assertNotIn ("Wrapped-Up Project" , names )
242+
243+
176244class PositionIntegrityCheckTests (DatabaseTestCase ):
177245 def test_no_position_and_self_advisor (self ):
178246 from datetime import date as _date
@@ -243,7 +311,10 @@ def test_get_rows_does_not_mutate_db(self):
243311 self .make_person (first_name = "Jane" , last_name = "Doe" )
244312 self .make_person (first_name = "Jane" , last_name = "Doe" )
245313 before = (Person .objects .count (), Publication .objects .count ())
246- for slug in ("duplicate-people" , "url-name-collisions" , "position-integrity" ):
314+ for slug in (
315+ "duplicate-people" , "url-name-collisions" , "position-integrity" ,
316+ "project-leadership" ,
317+ ):
247318 get_check (slug ).get_rows ()
248319 after = (Person .objects .count (), Publication .objects .count ())
249320 self .assertEqual (before , after )
0 commit comments