Skip to content

Commit e9d44d4

Browse files
rpcrossrjsparks
andauthored
feat: Capture volunteers from the registration system (ietf-tools#6605)
* feat: Capture volunteers from the registration system. Fixes ietf-tools#5938 * fix: allow withdrawn field to be null * docs: add explanatory code comments * fix: identify current nomcom by is_accepting_volunteers * fix: use auto_now_add instead of auto_now * fix: update migration --------- Co-authored-by: Robert Sparks <rjsparks@nostrum.com>
1 parent 20d7e8c commit e9d44d4

4 files changed

Lines changed: 93 additions & 3 deletions

File tree

ietf/api/tests.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
from ietf.group.factories import RoleFactory
2929
from ietf.meeting.factories import MeetingFactory, SessionFactory
3030
from ietf.meeting.models import Session
31+
from ietf.nomcom.models import Volunteer, NomCom
32+
from ietf.nomcom.factories import NomComFactory, nomcom_kwargs_for_year
3133
from ietf.person.factories import PersonFactory, random_faker
3234
from ietf.person.models import User
3335
from ietf.person.models import PersonalApiKey
@@ -630,6 +632,7 @@ def test_api_new_meeting_registration(self):
630632
'reg_type': 'hackathon',
631633
'ticket_type': '',
632634
'checkedin': 'False',
635+
'is_nomcom_volunteer': 'False',
633636
}
634637
url = urlreverse('ietf.api.views.api_new_meeting_registration')
635638
r = self.client.post(url, reg)
@@ -691,6 +694,50 @@ def test_api_new_meeting_registration(self):
691694
missing_fields = [f.strip() for f in fields.split(',')]
692695
self.assertEqual(set(missing_fields), set(drop_fields))
693696

697+
def test_api_new_meeting_registration_nomcom_volunteer(self):
698+
'''Test that Volunteer is created if is_nomcom_volunteer=True
699+
is submitted to API
700+
'''
701+
meeting = MeetingFactory(type_id='ietf')
702+
reg = {
703+
'apikey': 'invalid',
704+
'affiliation': "Alguma Corporação",
705+
'country_code': 'PT',
706+
'meeting': meeting.number,
707+
'reg_type': 'onsite',
708+
'ticket_type': '',
709+
'checkedin': 'False',
710+
'is_nomcom_volunteer': 'True',
711+
}
712+
person = PersonFactory()
713+
reg['email'] = person.email().address
714+
reg['first_name'] = person.first_name()
715+
reg['last_name'] = person.last_name()
716+
now = datetime.datetime.now()
717+
if now.month > 10:
718+
year = now.year + 1
719+
else:
720+
year = now.year
721+
# create appropriate group and nomcom objects
722+
nomcom = NomComFactory.create(is_accepting_volunteers=True, **nomcom_kwargs_for_year(year))
723+
url = urlreverse('ietf.api.views.api_new_meeting_registration')
724+
r = self.client.post(url, reg)
725+
self.assertContains(r, 'Invalid apikey', status_code=403)
726+
oidcp = PersonFactory(user__is_staff=True)
727+
# Make sure 'oidcp' has an acceptable role
728+
RoleFactory(name_id='robot', person=oidcp, email=oidcp.email(), group__acronym='secretariat')
729+
key = PersonalApiKey.objects.create(person=oidcp, endpoint=url)
730+
reg['apikey'] = key.hash()
731+
r = self.client.post(url, reg)
732+
nomcom = NomCom.objects.last()
733+
self.assertContains(r, "Accepted, New registration", status_code=202)
734+
# assert Volunteer exists
735+
self.assertEqual(Volunteer.objects.count(), 1)
736+
volunteer = Volunteer.objects.last()
737+
self.assertEqual(volunteer.person, person)
738+
self.assertEqual(volunteer.nomcom, nomcom)
739+
self.assertEqual(volunteer.origin, 'registration')
740+
694741
def test_api_version(self):
695742
DumpInfo.objects.create(date=timezone.datetime(2022,8,31,7,10,1,tzinfo=datetime.timezone.utc), host='testapi.example.com',tz='UTC')
696743
url = urlreverse('ietf.api.views.version')

ietf/api/views.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# Copyright The IETF Trust 2017-2020, All Rights Reserved
22
# -*- coding: utf-8 -*-
33

4-
54
import json
65
import pytz
76
import re
@@ -38,6 +37,7 @@
3837
from ietf.ietfauth.views import send_account_creation_email
3938
from ietf.ietfauth.utils import role_required
4039
from ietf.meeting.models import Meeting
40+
from ietf.nomcom.models import Volunteer, NomCom
4141
from ietf.stats.models import MeetingRegistration
4242
from ietf.utils import log
4343
from ietf.utils.decorators import require_api_key
@@ -140,7 +140,7 @@ def api_new_meeting_registration(request):
140140
def err(code, text):
141141
return HttpResponse(text, status=code, content_type='text/plain')
142142
required_fields = [ 'meeting', 'first_name', 'last_name', 'affiliation', 'country_code',
143-
'email', 'reg_type', 'ticket_type', 'checkedin']
143+
'email', 'reg_type', 'ticket_type', 'checkedin', 'is_nomcom_volunteer']
144144
fields = required_fields + []
145145
if request.method == 'POST':
146146
# parameters:
@@ -202,6 +202,19 @@ def err(code, text):
202202
else:
203203
send_account_creation_email(request, email)
204204
response += ", Email sent"
205+
206+
# handle nomcom volunteer
207+
if data['is_nomcom_volunteer'] and object.person:
208+
try:
209+
nomcom = NomCom.objects.get(is_accepting_volunteers=True)
210+
except (NomCom.DoesNotExist, NomCom.MultipleObjectsReturned):
211+
nomcom = None
212+
if nomcom:
213+
Volunteer.objects.create(
214+
nomcom=nomcom,
215+
person=object.person,
216+
affiliation=data['affiliation'],
217+
origin='registration')
205218
return HttpResponse(response, status=202, content_type='text/plain')
206219
else:
207220
return HttpResponse(status=405)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Generated by Django 4.2.7 on 2023-11-05 09:45
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
("nomcom", "0003_alter_nomination_share_nominator"),
9+
]
10+
11+
operations = [
12+
migrations.AddField(
13+
model_name="volunteer",
14+
name="origin",
15+
field=models.CharField(default="datatracker", max_length=32),
16+
),
17+
migrations.AddField(
18+
model_name="volunteer",
19+
name="time",
20+
field=models.DateTimeField(auto_now_add=True, null=True, blank=True),
21+
),
22+
migrations.AddField(
23+
model_name="volunteer",
24+
name="withdrawn",
25+
field=models.DateTimeField(blank=True, null=True),
26+
),
27+
]

ietf/nomcom/models.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,10 @@ class Volunteer(models.Model):
327327
nomcom = ForeignKey('NomCom')
328328
person = ForeignKey(Person)
329329
affiliation = models.CharField(blank=True, max_length=255)
330-
330+
time = models.DateTimeField(auto_now_add=True, null=True, blank=True)
331+
origin = models.CharField(max_length=32, default='datatracker')
332+
withdrawn = models.DateTimeField(blank=True, null=True)
333+
331334
def __str__(self):
332335
return f'{self.person} for {self.nomcom}'
333336

0 commit comments

Comments
 (0)