Skip to content

Commit 6bf4227

Browse files
committed
Checkpoint: main nomination forms use SearchableEmailField
- Legacy-Id: 10609
1 parent a2af7cf commit 6bf4227

8 files changed

Lines changed: 190 additions & 70 deletions

File tree

ietf/nomcom/factories.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def populate_positions(self, create, extracted, **kwargs):
9292
if extracted is None:
9393
extracted = True
9494
if create and extracted:
95-
nominees = [Nominee.objects.create(nomcom=self, email=PersonFactory().email_set.first()) for i in range(4)]
95+
nominees = [NomineeFactory(nomcom=self) for i in range(4)]
9696
positions = [PositionFactory(nomcom=self) for i in range(3)]
9797

9898
def npc(position,nominee,state_id):
@@ -134,6 +134,8 @@ class Meta:
134134
model = Nominee
135135

136136
nomcom = factory.SubFactory(NomComFactory)
137+
person = factory.SubFactory(PersonFactory)
138+
email = factory.LazyAttribute(lambda n: n.person.email())
137139

138140
class FeedbackFactory(factory.DjangoModelFactory):
139141
class Meta:

ietf/nomcom/forms.py

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
from django import forms
33
from django.contrib.formtools.preview import FormPreview, AUTO_ID
44
from django.shortcuts import get_object_or_404, redirect
5-
from django.template.loader import render_to_string
65
from django.utils.decorators import method_decorator
76
from django.shortcuts import render_to_response
87
from django.template.context import RequestContext
@@ -15,8 +14,10 @@
1514
Position, Feedback, ReminderDates )
1615
from ietf.nomcom.utils import (NOMINATION_RECEIPT_TEMPLATE, FEEDBACK_RECEIPT_TEMPLATE,
1716
get_user_email, validate_private_key, validate_public_key,
18-
get_or_create_nominee, create_feedback_email)
17+
get_or_create_nominee, get_or_create_nominee_by_person,
18+
create_feedback_email)
1919
from ietf.person.models import Email
20+
from ietf.person.fields import SearchableEmailField
2021
from ietf.utils.fields import MultiEmailField
2122
from ietf.utils.mail import send_mail
2223
from ietf.mailtrigger.utils import gather_address_lists
@@ -299,7 +300,8 @@ def save(self):
299300

300301

301302
class NominateForm(forms.ModelForm):
302-
comments = forms.CharField(label="Candidate's qualifications for the position",
303+
candidate = SearchableEmailField(only_users=False)
304+
qualifications = forms.CharField(label="Candidate's qualifications for the position",
303305
widget=forms.Textarea())
304306
confirmation = forms.BooleanField(label='Email comments back to me as confirmation.',
305307
help_text="If you want to get a confirmation mail containing your feedback in cleartext, please check the 'email comments back to me as confirmation'.",
@@ -315,9 +317,10 @@ def __init__(self, *args, **kwargs):
315317
self.fields['nominator_email'].label = 'Nominator email'
316318
if self.nomcom:
317319
self.fields['position'].queryset = Position.objects.get_by_nomcom(self.nomcom).opened()
318-
self.fields['comments'].help_text = self.nomcom.initial_text
320+
self.fields['qualifications'].help_text = self.nomcom.initial_text
319321

320322
if not self.public:
323+
self.fields.pop('confirmation')
321324
author = get_user_email(self.user)
322325
if author:
323326
self.fields['nominator_email'].initial = author.address
@@ -329,33 +332,39 @@ def __init__(self, *args, **kwargs):
329332
has indicated they will allow NomCom to share their name as one of the people
330333
nominating this candidate."""
331334
else:
332-
pass
335+
self.fields.pop('nominator_email')
333336

334337

335338
def save(self, commit=True):
336339
# Create nomination
337340
nomination = super(NominateForm, self).save(commit=False)
338341
nominator_email = self.cleaned_data.get('nominator_email', None)
339-
candidate_email = self.cleaned_data['candidate_email']
340-
candidate_name = self.cleaned_data['candidate_name']
342+
## TODO - rename this candidate_email after purging the old candidate_email
343+
candidate = self.cleaned_data['candidate']
344+
##candidate_email = self.cleaned_data['candidate_email']
345+
##candidate_name = self.cleaned_data['candidate_name']
341346
position = self.cleaned_data['position']
342-
comments = self.cleaned_data['comments']
343-
confirmation = self.cleaned_data['confirmation']
347+
qualifications = self.cleaned_data['qualifications']
348+
confirmation = self.cleaned_data.get('confirmation', False)
344349
share_nominator = self.cleaned_data['share_nominator']
345350
nomcom_template_path = '/nomcom/%s/' % self.nomcom.group.acronym
346351

352+
nomination.candidate_name = candidate.person.plain_name()
353+
nomination.candidate_email = candidate.address
354+
347355
author = None
348356
if self.public:
349357
author = get_user_email(self.user)
350358
else:
351359
if nominator_email:
352360
emails = Email.objects.filter(address=nominator_email)
353361
author = emails and emails[0] or None
354-
nominee = get_or_create_nominee(self.nomcom, candidate_name, candidate_email, position, author)
362+
##nominee = get_or_create_nominee(self.nomcom, candidate_name, candidate_email, position, author)
363+
nominee = get_or_create_nominee_by_person (self.nomcom, candidate.person, position, author)
355364

356365
# Complete nomination data
357366
feedback = Feedback.objects.create(nomcom=self.nomcom,
358-
comments=comments,
367+
comments=qualifications,
359368
type=FeedbackTypeName.objects.get(slug='nomina'),
360369
user=self.user)
361370
feedback.positions.add(position)
@@ -381,7 +390,7 @@ def save(self, commit=True):
381390
from_email = settings.NOMCOM_FROM_EMAIL
382391
(to_email, cc) = gather_address_lists('nomination_receipt_requested',nominator=author.address)
383392
context = {'nominee': nominee.email.person.name,
384-
'comments': comments,
393+
'comments': qualifications,
385394
'position': position.name}
386395
path = nomcom_template_path + NOMINATION_RECEIPT_TEMPLATE
387396
send_mail(None, to_email, from_email, subject, path, context, cc=cc)
@@ -390,8 +399,10 @@ def save(self, commit=True):
390399

391400
class Meta:
392401
model = Nomination
393-
fields = ('share_nominator', 'position', 'nominator_email', 'candidate_name',
394-
'candidate_email', 'candidate_phone')
402+
fields = ('share_nominator', 'position', 'nominator_email', 'candidate',
403+
'candidate_phone', 'qualifications', 'confirmation')
404+
##fields = ('share_nominator', 'position', 'nominator_email', 'candidate', 'candidate_name',
405+
## 'candidate_email', 'candidate_phone', 'qualifications', 'confirmation')
395406

396407

397408
class FeedbackForm(forms.ModelForm):

ietf/nomcom/tests.py

Lines changed: 98 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
from ietf.nomcom.factories import NomComFactory, FeedbackFactory, \
3535
nomcom_kwargs_for_year, provide_private_key_to_test_client, \
3636
key
37-
from ietf.person.factories import PersonFactory
37+
from ietf.person.factories import PersonFactory, EmailFactory
3838
from ietf.dbtemplate.factories import DBTemplateFactory
3939
from ietf.dbtemplate.models import DBTemplate
4040

@@ -481,11 +481,7 @@ def test_public_nominate(self):
481481

482482
self.nominate_view(public=True,confirmation=True)
483483

484-
self.assertEqual(len(outbox), messages_before + 4)
485-
486-
self.assertTrue('New person' in outbox[-4]['Subject'])
487-
self.assertTrue('nomcomchair' in outbox[-4]['To'])
488-
self.assertTrue('secretariat' in outbox[-4]['To'])
484+
self.assertEqual(len(outbox), messages_before + 3)
489485

490486
self.assertEqual('IETF Nomination Information', outbox[-3]['Subject'])
491487
self.assertTrue('nominee' in outbox[-3]['To'])
@@ -518,15 +514,23 @@ def test_public_nominate_with_automatic_questionnaire(self):
518514
login_testing_unauthorized(self, COMMUNITY_USER, self.public_nominate_url)
519515
empty_outbox()
520516
self.nominate_view(public=True)
521-
self.assertEqual(len(outbox), 4)
517+
self.assertEqual(len(outbox), 3)
522518
# test_public_nominate checks the other messages
523-
self.assertTrue('Questionnaire' in outbox[2]['Subject'])
524-
self.assertTrue('nominee@' in outbox[2]['To'])
519+
self.assertTrue('Questionnaire' in outbox[1]['Subject'])
520+
self.assertTrue('nominee@' in outbox[1]['To'])
525521

526522

527523
def nominate_view(self, *args, **kwargs):
528524
public = kwargs.pop('public', True)
525+
nominee = kwargs.pop('nominee', None)
529526
nominee_email = kwargs.pop('nominee_email', u'nominee@example.com')
527+
if not nominee:
528+
nominee = Email.objects.filter(address=nominee_email).first()
529+
if not nominee:
530+
nominee = EmailFactory(address=nominee_email,primary=True)
531+
if not nominee.person:
532+
nominee.person = PersonFactory()
533+
nominee.save()
530534
nominator_email = kwargs.pop('nominator_email', "%s%s" % (COMMUNITY_USER, EMAIL_DOMAIN))
531535
position_name = kwargs.pop('position', 'IAOC')
532536
confirmation = kwargs.pop('confirmation', False)
@@ -553,16 +557,13 @@ def nominate_view(self, *args, **kwargs):
553557
self.assertEqual(len(q("#nominate-form")), 1)
554558

555559
position = Position.objects.get(name=position_name)
556-
candidate_email = nominee_email
557-
candidate_name = u'nominee'
558560
comments = u'Test nominate view. Comments with accents äöåÄÖÅ éáíóú âêîôû ü àèìòù.'
559561
candidate_phone = u'123456'
560562

561-
test_data = {'candidate_name': candidate_name,
562-
'candidate_email': candidate_email,
563+
test_data = {'candidate': nominee.pk,
563564
'candidate_phone': candidate_phone,
564565
'position': position.id,
565-
'comments': comments,
566+
'qualifications': comments,
566567
'confirmation': confirmation}
567568
if not public:
568569
test_data['nominator_email'] = nominator_email
@@ -573,12 +574,11 @@ def nominate_view(self, *args, **kwargs):
573574
self.assertContains(response, "alert-success")
574575

575576
# check objects
576-
email = Email.objects.get(address=candidate_email)
577-
Person.objects.get(name=candidate_name, address=candidate_email)
578-
nominee = Nominee.objects.get(email=email)
579-
NomineePosition.objects.get(position=position, nominee=nominee)
577+
## TODO - straighten this _obj vs _email naming mess out
578+
nominee_obj = Nominee.objects.get(email=nominee)
579+
NomineePosition.objects.get(position=position, nominee=nominee_obj)
580580
feedback = Feedback.objects.filter(positions__in=[position],
581-
nominees__in=[nominee],
581+
nominees__in=[nominee_obj],
582582
type=FeedbackTypeName.objects.get(slug='nomina')).latest('id')
583583
if public:
584584
self.assertEqual(feedback.author, nominator_email)
@@ -588,13 +588,85 @@ def nominate_view(self, *args, **kwargs):
588588

589589
self.assertEqual(check_comments(feedback.comments, comments, self.privatekey_file), True)
590590
Nomination.objects.get(position=position,
591-
candidate_name=candidate_name,
592-
candidate_email=candidate_email,
591+
candidate_name=nominee.person.plain_name(),
592+
candidate_email=nominee.address,
593593
candidate_phone=candidate_phone,
594-
nominee=nominee,
594+
nominee=nominee_obj,
595595
comments=feedback,
596596
nominator_email="%s%s" % (COMMUNITY_USER, EMAIL_DOMAIN))
597597

598+
## Save this for repurposing to test the to-be-created 'by name and address' form
599+
## def nominate_view(self, *args, **kwargs):
600+
## public = kwargs.pop('public', True)
601+
## nominee_email = kwargs.pop('nominee_email', u'nominee@example.com')
602+
## nominator_email = kwargs.pop('nominator_email', "%s%s" % (COMMUNITY_USER, EMAIL_DOMAIN))
603+
## position_name = kwargs.pop('position', 'IAOC')
604+
## confirmation = kwargs.pop('confirmation', False)
605+
##
606+
## if public:
607+
## nominate_url = self.public_nominate_url
608+
## else:
609+
## nominate_url = self.private_nominate_url
610+
## response = self.client.get(nominate_url)
611+
## self.assertEqual(response.status_code, 200)
612+
##
613+
## nomcom = get_nomcom_by_year(self.year)
614+
## if not nomcom.public_key:
615+
## q = PyQuery(response.content)
616+
## self.assertEqual(len(q("#nominate-form")), 0)
617+
##
618+
## # save the cert file in tmp
619+
## nomcom.public_key.storage.location = tempfile.gettempdir()
620+
## nomcom.public_key.save('cert', File(open(self.cert_file.name, 'r')))
621+
##
622+
## response = self.client.get(nominate_url)
623+
## self.assertEqual(response.status_code, 200)
624+
## q = PyQuery(response.content)
625+
## self.assertEqual(len(q("#nominate-form")), 1)
626+
##
627+
## position = Position.objects.get(name=position_name)
628+
## candidate_email = nominee_email
629+
## candidate_name = u'nominee'
630+
## comments = u'Test nominate view. Comments with accents äöåÄÖÅ éáíóú âêîôû ü àèìòù.'
631+
## candidate_phone = u'123456'
632+
##
633+
## test_data = {'candidate_name': candidate_name,
634+
## 'candidate_email': candidate_email,
635+
## 'candidate_phone': candidate_phone,
636+
## 'position': position.id,
637+
## 'qualifications': comments,
638+
## 'confirmation': confirmation}
639+
## if not public:
640+
## test_data['nominator_email'] = nominator_email
641+
##
642+
## response = self.client.post(nominate_url, test_data)
643+
## self.assertEqual(response.status_code, 200)
644+
## q = PyQuery(response.content)
645+
## self.assertContains(response, "alert-success")
646+
##
647+
## # check objects
648+
## email = Email.objects.get(address=candidate_email)
649+
## Person.objects.get(name=candidate_name, address=candidate_email)
650+
## nominee = Nominee.objects.get(email=email)
651+
## NomineePosition.objects.get(position=position, nominee=nominee)
652+
## feedback = Feedback.objects.filter(positions__in=[position],
653+
## nominees__in=[nominee],
654+
## type=FeedbackTypeName.objects.get(slug='nomina')).latest('id')
655+
## if public:
656+
## self.assertEqual(feedback.author, nominator_email)
657+
##
658+
## # to check feedback comments are saved like enrypted data
659+
## self.assertNotEqual(feedback.comments, comments)
660+
##
661+
## self.assertEqual(check_comments(feedback.comments, comments, self.privatekey_file), True)
662+
## Nomination.objects.get(position=position,
663+
## candidate_name=candidate_name,
664+
## candidate_email=candidate_email,
665+
## candidate_phone=candidate_phone,
666+
## nominee=nominee,
667+
## comments=feedback,
668+
## nominator_email="%s%s" % (COMMUNITY_USER, EMAIL_DOMAIN))
669+
##
598670
def test_add_questionnaire(self):
599671
self.access_chair_url(self.add_questionnaire_url)
600672
return self.add_questionnaire()
@@ -656,10 +728,10 @@ def test_public_feedback(self):
656728
self.feedback_view(public=True,confirmation=True)
657729
# feedback_view does a nomination internally: there is a lot of email related to that - tested elsewhere
658730
# We're interested in the confirmation receipt here
659-
self.assertEqual(len(outbox),4)
660-
self.assertEqual('NomCom comment confirmation', outbox[3]['Subject'])
661-
self.assertTrue('plain' in outbox[3]['To'])
662-
self.assertTrue(u'Comments with accents äöå' in unicode(outbox[3].get_payload(decode=True),"utf-8","replace"))
731+
self.assertEqual(len(outbox),3)
732+
self.assertEqual('NomCom comment confirmation', outbox[2]['Subject'])
733+
self.assertTrue('plain' in outbox[2]['To'])
734+
self.assertTrue(u'Comments with accents äöå' in unicode(outbox[2].get_payload(decode=True),"utf-8","replace"))
663735

664736
empty_outbox()
665737
self.feedback_view(public=True)

0 commit comments

Comments
 (0)