3131from ietf .nomcom .management .commands .send_reminders import Command , is_time_to_send
3232
3333from ietf .nomcom .factories import NomComFactory , FeedbackFactory , \
34- nomcom_kwargs_for_year , provide_private_key_to_test_client
34+ nomcom_kwargs_for_year , provide_private_key_to_test_client , \
35+ key
3536from ietf .person .factories import PersonFactory
3637from ietf .dbtemplate .factories import DBTemplateFactory
3738
@@ -1199,6 +1200,37 @@ def test_help(self):
11991200 response = self .client .get (url )
12001201 self .assertEqual (response .status_code ,200 )
12011202
1203+ def test_accept_reject_nomination_edges (self ):
1204+
1205+ np = self .nc .nominee_set .first ().nomineeposition_set .first ()
1206+
1207+ kwargs = {'year' :self .nc .year (),
1208+ 'nominee_position_id' :np .id ,
1209+ 'state' :'accepted' ,
1210+ 'date' :np .time .strftime ("%Y%m%d" ),
1211+ 'hash' :get_hash_nominee_position (np .time .strftime ("%Y%m%d" ),np .id ),
1212+ }
1213+ url = reverse ('nomcom_process_nomination_status' , kwargs = kwargs )
1214+ response = self .client .get (url )
1215+ self .assertEqual (response .status_code ,403 )
1216+ self .assertTrue ('already was' in unicontent (response ))
1217+
1218+ settings .DAYS_TO_EXPIRE_NOMINATION_LINK = 2
1219+ np .time = np .time - datetime .timedelta (days = 3 )
1220+ np .save ()
1221+ kwargs ['date' ] = np .time .strftime ("%Y%m%d" )
1222+ kwargs ['hash' ] = get_hash_nominee_position (np .time .strftime ("%Y%m%d" ),np .id )
1223+ url = reverse ('nomcom_process_nomination_status' , kwargs = kwargs )
1224+ response = self .client .get (url )
1225+ self .assertEqual (response .status_code ,403 )
1226+ self .assertTrue ('Link expired' in unicontent (response ))
1227+
1228+ kwargs ['hash' ] = 'bad'
1229+ url = reverse ('nomcom_process_nomination_status' , kwargs = kwargs )
1230+ response = self .client .get (url )
1231+ self .assertEqual (response .status_code ,403 )
1232+ self .assertTrue ('Bad hash!' in unicontent (response ))
1233+
12021234 def test_accept_reject_nomination_comment (self ):
12031235 np = self .nc .nominee_set .first ().nomineeposition_set .first ()
12041236 hash = get_hash_nominee_position (np .time .strftime ("%Y%m%d" ),np .id )
@@ -1224,4 +1256,188 @@ def test_accept_reject_nomination_comment(self):
12241256 response = self .client .post (url ,{'comments' :'A nonempty comment' })
12251257 self .assertEqual (response .status_code ,200 )
12261258 self .assertEqual (Feedback .objects .count (),feedback_count_before + 1 )
1259+
1260+ def test_provide_private_key (self ):
1261+ url = reverse ('nomcom_private_key' ,kwargs = {'year' :self .nc .year ()})
1262+ login_testing_unauthorized (self ,self .chair .user .username ,url )
1263+ response = self .client .get (url )
1264+ self .assertEqual (response .status_code ,200 )
1265+ response = self .client .post (url ,{'key' :key })
1266+ self .assertEqual (response .status_code ,302 )
1267+
1268+ def test_email_pasting (self ):
1269+ url = reverse ('nomcom_private_feedback_email' ,kwargs = {'year' :self .nc .year ()})
1270+ login_testing_unauthorized (self ,self .chair .user .username ,url )
1271+ response = self .client .get (url )
1272+ self .assertTrue (response .status_code ,200 )
1273+ fb_count_before = Feedback .objects .count ()
1274+ response = self .client .post (url ,{'email_text' :"""To: rjsparks@nostrum.com
1275+ From: Robert Sparks <rjsparks@nostrum.com>
1276+ Subject: Junk message for feedback testing
1277+ Message-ID: <566F2FE5.1050401@nostrum.com>
1278+ Date: Mon, 14 Dec 2015 15:08:53 -0600
1279+ Content-Type: text/plain; charset=utf-8; format=flowed
1280+ Content-Transfer-Encoding: 7bit
1281+
1282+ Junk body for testing
1283+
1284+ """ })
1285+ self .assertEqual (response .status_code ,200 )
1286+ self .assertEqual (Feedback .objects .count (),fb_count_before + 1 )
1287+
1288+ def test_simple_feedback_pending (self ):
1289+ url = reverse ('nomcom_view_feedback_pending' ,kwargs = {'year' :self .nc .year () })
1290+ login_testing_unauthorized (self , self .chair .user .username , url )
1291+ provide_private_key_to_test_client (self )
1292+
1293+ # test simple classification when there's only one thing to classify
1294+
1295+ # junk is the only category you can set directly from the first form the view presents
1296+ fb = FeedbackFactory (nomcom = self .nc ,type_id = None )
1297+ response = self .client .get (url )
1298+ self .assertEqual (response .status_code ,200 )
1299+
1300+ response = self .client .post (url , {'form-TOTAL_FORMS' : 1 ,
1301+ 'form-INITIAL_FORMS' : 1 ,
1302+ 'form-0-id' : fb .id ,
1303+ 'form-0-type' : 'junk' ,
1304+ })
1305+ self .assertEqual (response .status_code ,302 )
1306+ fb = Feedback .objects .get (id = fb .id )
1307+ self .assertEqual (fb .type_id ,'junk' )
1308+
1309+ # comments, nominations, and questionnare responses are catagorized via a second
1310+ # formset presented by the view (signaled by having 'end' appear in the POST)
1311+ fb = FeedbackFactory (nomcom = self .nc ,type_id = None )
1312+ np = NomineePosition .objects .filter (position__nomcom = self .nc ,state = 'accepted' ).first ()
1313+ fb_count_before = np .nominee .feedback_set .count ()
1314+ response = self .client .post (url , {'form-TOTAL_FORMS' :1 ,
1315+ 'form-INITIAL_FORMS' :1 ,
1316+ 'end' :'Save feedback' ,
1317+ 'form-0-id' : fb .id ,
1318+ 'form-0-type' : 'comment' ,
1319+ 'form-0-nominee' : '%s_%s' % (np .position .id ,np .nominee .id ),
1320+ })
1321+ self .assertEqual (response .status_code ,302 )
1322+ fb = Feedback .objects .get (id = fb .id )
1323+ self .assertEqual (fb .type_id ,'comment' )
1324+ self .assertEqual (np .nominee .feedback_set .count (),fb_count_before + 1 )
1325+
1326+ fb = FeedbackFactory (nomcom = self .nc ,type_id = None )
1327+ nominee = self .nc .nominee_set .first ()
1328+ position = self .nc .position_set .exclude (nomineeposition__nominee = nominee ).first ()
1329+ self .assertIsNotNone (position )
1330+ fb_count_before = nominee .feedback_set .count ()
1331+ response = self .client .post (url , {'form-TOTAL_FORMS' :1 ,
1332+ 'form-INITIAL_FORMS' :1 ,
1333+ 'end' :'Save feedback' ,
1334+ 'form-0-id' : fb .id ,
1335+ 'form-0-type' : 'nomina' ,
1336+ 'form-0-position' : position .id ,
1337+ 'form-0-candidate_name' : nominee .name (),
1338+ 'form-0-candidate_email' : nominee .email .address ,
1339+ })
1340+ self .assertEqual (response .status_code ,302 )
1341+ fb = Feedback .objects .get (id = fb .id )
1342+ self .assertEqual (fb .type_id ,'nomina' )
1343+ self .assertEqual (nominee .feedback_set .count (),fb_count_before + 1 )
1344+
1345+ fb = FeedbackFactory (nomcom = self .nc ,type_id = None )
1346+ np = NomineePosition .objects .filter (position__nomcom = self .nc ,state = 'accepted' ).first ()
1347+ fb_count_before = np .nominee .feedback_set .count ()
1348+ response = self .client .post (url , {'form-TOTAL_FORMS' :1 ,
1349+ 'form-INITIAL_FORMS' :1 ,
1350+ 'end' :'Save feedback' ,
1351+ 'form-0-id' : fb .id ,
1352+ 'form-0-type' : 'questio' ,
1353+ 'form-0-nominee' : '%s_%s' % (np .position .id ,np .nominee .id ),
1354+ })
1355+ self .assertEqual (response .status_code ,302 )
1356+ fb = Feedback .objects .get (id = fb .id )
1357+ self .assertEqual (fb .type_id ,'questio' )
1358+ self .assertEqual (np .nominee .feedback_set .count (),fb_count_before + 1 )
1359+
1360+ def test_complicated_feedback_pending (self ):
1361+ url = reverse ('nomcom_view_feedback_pending' ,kwargs = {'year' :self .nc .year () })
1362+ login_testing_unauthorized (self , self .chair .user .username , url )
1363+ provide_private_key_to_test_client (self )
1364+
1365+ # Test having multiple things to classify
1366+ # The view has some complicated to handle having some forms in the initial form formset
1367+ # being categorized as 'junk' and others being categorized as something that requires
1368+ # more information. The second formset presented will have forms for any others initially
1369+ # categorized as nominations, then a third formset will be presented with any that were
1370+ # initially categorized as comments or questionnaire responses. The following exercises
1371+ # all the gears that glue these three formset presentations together.
12271372
1373+ fb0 = FeedbackFactory (nomcom = self .nc ,type_id = None )
1374+ fb1 = FeedbackFactory (nomcom = self .nc ,type_id = None )
1375+ fb2 = FeedbackFactory (nomcom = self .nc ,type_id = None )
1376+ nominee = self .nc .nominee_set .first ()
1377+ new_position_for_nominee = self .nc .position_set .exclude (nomineeposition__nominee = nominee ).first ()
1378+
1379+ # Initial formset
1380+ response = self .client .post (url , {'form-TOTAL_FORMS' : 3 ,
1381+ 'form-INITIAL_FORMS' : 3 ,
1382+ 'form-0-id' : fb0 .id ,
1383+ 'form-0-type' : 'junk' ,
1384+ 'form-1-id' : fb1 .id ,
1385+ 'form-1-type' : 'nomina' ,
1386+ 'form-2-id' : fb2 .id ,
1387+ 'form-2-type' : 'comment' ,
1388+ })
1389+ self .assertEqual (response .status_code ,200 ) # Notice that this is not a 302
1390+ fb0 = Feedback .objects .get (id = fb0 .id )
1391+ self .assertEqual (fb0 .type_id ,'junk' )
1392+ q = PyQuery (response .content )
1393+ self .assertEqual (q ('input[name=\" form-0-type\" ]' ).attr ['value' ],'nomina' )
1394+ self .assertEqual (q ('input[name=\" extra_ids\" ]' ).attr ['value' ],'%s:comment' % fb2 .id )
1395+
1396+ # Second formset
1397+ response = self .client .post (url , {'form-TOTAL_FORMS' :1 ,
1398+ 'form-INITIAL_FORMS' :1 ,
1399+ 'end' :'Save feedback' ,
1400+ 'form-0-id' : fb1 .id ,
1401+ 'form-0-type' : 'nomina' ,
1402+ 'form-0-position' : new_position_for_nominee .id ,
1403+ 'form-0-candidate_name' : nominee .name (),
1404+ 'form-0-candidate_email' : nominee .email .address ,
1405+ 'extra_ids' : '%s:comment' % fb2 .id ,
1406+ })
1407+ self .assertEqual (response .status_code ,200 ) # Notice that this is also is not a 302
1408+ fb1 = Feedback .objects .get (id = fb1 .id )
1409+ self .assertEqual (fb1 .type_id ,'nomina' )
1410+ q = PyQuery (response .content )
1411+ self .assertEqual (q ('input[name=\" form-0-type\" ]' ).attr ['value' ],'comment' )
1412+ self .assertFalse (q ('input[name=\" extra_ids\" ]' ))
1413+
1414+ # Exercising the resulting third formset is identical to the simple test above
1415+ # that categorizes a single thing as a comment. Note that it returns a 302.
1416+
1417+ # There is yet another code-path for transitioning to the second form when
1418+ # nothing was classified as a nomination.
1419+ fb0 = FeedbackFactory (nomcom = self .nc ,type_id = None )
1420+ fb1 = FeedbackFactory (nomcom = self .nc ,type_id = None )
1421+ np = NomineePosition .objects .filter (position__nomcom = self .nc ,state = 'accepted' ).first ()
1422+ response = self .client .post (url , {'form-TOTAL_FORMS' : 2 ,
1423+ 'form-INITIAL_FORMS' : 2 ,
1424+ 'form-0-id' : fb0 .id ,
1425+ 'form-0-type' : 'junk' ,
1426+ 'form-1-id' : fb1 .id ,
1427+ 'form-1-type' : 'comment' ,
1428+ })
1429+ self .assertEqual (response .status_code ,200 )
1430+ q = PyQuery (response .content )
1431+ self .assertEqual (q ('input[name=\" form-0-type\" ]' ).attr ['value' ],'comment' )
1432+ self .assertFalse (q ('input[name=\" extra_ids\" ]' ))
1433+
1434+
1435+ class NomComIndexTests (TestCase ):
1436+ def setUp (self ):
1437+ for year in range (2000 ,2014 ):
1438+ NomComFactory .create (** nomcom_kwargs_for_year (year = year ,populate_positions = False ,populate_personnel = False ))
1439+
1440+ def testIndex (self ):
1441+ url = reverse ('ietf.nomcom.views.index' )
1442+ response = self .client .get (url )
1443+ self .assertEqual (response .status_code ,200 )
0 commit comments