Merged in [18324] from rjsparks@nostrum.com:

Send extra mail to yangdoctors chairs when a draft with yang checks goes into IETF LC. Fixes #2419.
 - Legacy-Id: 18363
Note: SVN reference [18324] has been migrated to Git commit cb58810705
This commit is contained in:
Henrik Levkowetz 2020-08-13 11:23:22 +00:00
commit 9125104065
9 changed files with 125 additions and 6 deletions

View file

@ -635,3 +635,12 @@ def email_charter_internal_review(request, charter):
cc=addrs.cc,
extra={'Reply-To': ["irsg@irtf.org" if charter.group.type_id == 'rg' else "iesg@ietf.org", ]},
)
def email_lc_to_yang_doctors(request, doc):
addrs = gather_address_lists('last_call_of_doc_with_yang_issued')
send_mail(request, addrs.to, settings.DEFAULT_FROM_EMAIL,
'Attn YangDoctors: IETF LC issued for %s' % doc.name ,
'doc/mail/lc_to_yang_doctors.txt',
dict(doc=doc, url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url() ),
cc = addrs.cc,
)

View file

@ -1220,6 +1220,7 @@ class EmailAliasesTests(TestCase):
def setUp(self):
WgDraftFactory(name='draft-ietf-mars-test',group__acronym='mars')
WgDraftFactory(name='draft-ietf-ames-test',group__acronym='ames')
RoleFactory(group__type_id='review', group__acronym='yangdoctors', name_id='secr')
self.doc_alias_file = NamedTemporaryFile(delete=False, mode='w+')
self.doc_alias_file.write("""# Generated by hand at 2015-02-12_16:26:45
virtual.ietf.org anything

View file

@ -16,7 +16,7 @@ from ietf.doc.models import ( Document, State, DocEvent,
from ietf.doc.factories import DocumentFactory, IndividualDraftFactory, IndividualRfcFactory, WgDraftFactory
from ietf.doc.utils import create_ballot_if_not_open
from ietf.group.models import Group, Role
from ietf.group.factories import GroupFactory, RoleFactory
from ietf.group.factories import GroupFactory, RoleFactory, ReviewTeamFactory
from ietf.ipr.factories import HolderIprDisclosureFactory
from ietf.name.models import BallotPositionName
from ietf.iesg.models import TelechatDate
@ -804,6 +804,42 @@ class MakeLastCallTests(TestCase):
self.assertTrue("Last Call" in draft.message_set.order_by("-time")[0].subject)
def test_make_last_call_yang_document(self):
yd = ReviewTeamFactory(acronym='yangdoctors')
secr_email = RoleFactory(group=yd,name_id='secr').person.email().address
draft = WgDraftFactory()
submission = draft.submission_set.create(
state_id = 'posted',
name = draft.name,
group = draft.group,
rev = draft.rev,
authors = '[]',
)
submission.checks.create(
checker = 'yang validation',
passed = True,
)
url = urlreverse('ietf.doc.views_ballot.make_last_call', kwargs=dict(name=draft.name))
login_testing_unauthorized(self, 'secretary', url)
mailbox_before = len(outbox)
last_call_sent_date = datetime.date.today()
expire_date = last_call_sent_date+datetime.timedelta(days=14)
r = self.client.post(url,
dict(last_call_sent_date=last_call_sent_date,
last_call_expiration_date=expire_date
))
self.assertEqual(r.status_code, 302)
self.assertEqual(len(outbox), mailbox_before + 3)
self.assertIn("ietf-announce@", outbox[-3]['To'])
self.assertIn("drafts-lastcall@icann.org", outbox[-2]['To'])
self.assertIn(secr_email, outbox[-1]['To'])
class DeferUndeferTestCase(TestCase):
def helper_test_defer(self,name):

View file

@ -26,7 +26,8 @@ from ietf.doc.utils import ( add_state_change_event, close_ballot, close_open_ba
from ietf.doc.mails import ( email_ballot_deferred, email_ballot_undeferred,
extra_automation_headers, generate_last_call_announcement,
generate_issue_ballot_mail, generate_ballot_writeup, generate_ballot_rfceditornote,
generate_approval_mail, email_irsg_ballot_closed, email_irsg_ballot_issued )
generate_approval_mail, email_irsg_ballot_closed, email_irsg_ballot_issued,
email_lc_to_yang_doctors )
from ietf.doc.lastcall import request_last_call
from ietf.doc.templatetags.ietf_filters import can_ballot
from ietf.iesg.models import TelechatDate
@ -1046,6 +1047,10 @@ def make_last_call(request, name):
doc.save_with_history(events)
sub = doc.submission()
if sub and sub.has_yang():
email_lc_to_yang_doctors(request, doc)
return HttpResponseRedirect(doc.get_absolute_url())
else:
initial = {}

View file

@ -0,0 +1,38 @@
# Copyright The IETF Trust 2019-2020, All Rights Reserved
from django.db import migrations
def forward(apps, schema_editor):
MailTrigger = apps.get_model('mailtrigger', 'MailTrigger')
Recipient = apps.get_model('mailtrigger', 'Recipient')
Recipient.objects.create(
slug = 'yang_doctors_secretaries',
desc = 'Yang Doctors Secretaries',
template = ''
)
lc_to_yang_doctors = MailTrigger.objects.create(
slug='last_call_of_doc_with_yang_issued',
desc='Recipients when IETF LC is issued on a document with yang checks',
)
lc_to_yang_doctors.to.set(Recipient.objects.filter(slug='yang_doctors_secretaries'))
def reverse(apps, schema_editor):
MailTrigger = apps.get_model('mailtrigger', 'MailTrigger')
Recipient = apps.get_model('mailtrigger', 'Recipient')
MailTrigger.objects.filter(slug='last_call_of_doc_with_yang_issued').delete()
Recipient.objects.filter(slug='yang_doctors_secretaries').delete()
class Migration(migrations.Migration):
dependencies = [
('mailtrigger', '0016_add_irsg_ballot_issued'),
]
operations = [
migrations.RunPython(forward, reverse),
]

View file

@ -7,6 +7,7 @@ from django.template import Template, Context
from email.utils import parseaddr
from ietf.utils.mail import formataddr, get_email_addresses_from_text
from ietf.group.models import Group
from ietf.person.models import Email, Alias
from ietf.review.models import ReviewTeamSettings
@ -367,3 +368,6 @@ class Recipient(models.Model):
for role in review_req.team.parent.role_set.filter(name='ad'):
addrs.append(role.email.address)
return addrs
def gather_yang_doctors_secretaries(self, **kwargs):
return self.gather_group_secretaries(group=Group.objects.get(acronym='yangdoctors'))

View file

@ -3940,6 +3940,17 @@
"model": "mailtrigger.mailtrigger",
"pk": "last_call_issued_iana"
},
{
"fields": {
"cc": [],
"desc": "Recipients when IETF LC is issued on a document with yang checks",
"to": [
"yang_doctors_secretaries"
]
},
"model": "mailtrigger.mailtrigger",
"pk": "last_call_of_doc_with_yang_issued"
},
{
"fields": {
"cc": [
@ -5543,6 +5554,14 @@
"model": "mailtrigger.recipient",
"pk": "submission_submitter"
},
{
"fields": {
"desc": "Yang Doctors Secretaries",
"template": ""
},
"model": "mailtrigger.recipient",
"pk": "yang_doctors_secretaries"
},
{
"fields": {
"name": "Area meetings cannot conflict with anything else in their area",
@ -14886,7 +14905,7 @@
"fields": {
"command": "xym",
"switch": "--version",
"time": "2020-08-04T00:13:15.604",
"time": "2020-08-12T00:12:54.984",
"used": true,
"version": "xym 0.4.8"
},
@ -14897,7 +14916,7 @@
"fields": {
"command": "pyang",
"switch": "--version",
"time": "2020-08-04T00:13:16.892",
"time": "2020-08-12T00:12:56.359",
"used": true,
"version": "pyang 2.3.2"
},
@ -14908,7 +14927,7 @@
"fields": {
"command": "yanglint",
"switch": "--version",
"time": "2020-08-04T00:13:17.151",
"time": "2020-08-12T00:12:56.632",
"used": true,
"version": "yanglint SO 1.6.7"
},
@ -14919,7 +14938,7 @@
"fields": {
"command": "xml2rfc",
"switch": "--version",
"time": "2020-08-04T00:13:18.980",
"time": "2020-08-12T00:12:58.366",
"used": true,
"version": "xml2rfc 2.47.0"
},

View file

@ -73,6 +73,9 @@ class Submission(models.Model):
def latest_checks(self):
checks = [ self.checks.filter(checker=c).latest('time') for c in self.checks.values_list('checker', flat=True).distinct() ]
return checks
def has_yang(self):
return any ( [ c.checker=='yang validation' and c.passed is not None for c in self.latest_checks()] )
class SubmissionCheck(models.Model):
time = models.DateTimeField(default=datetime.datetime.now)

View file

@ -0,0 +1,4 @@
{% load ietf_filters %}{% autoescape off %}{% filter wordwrap:78 %}
IETF Last Call has been issued for a document with yang checks.
The document is available at {{ url }}{% endfilter %}{% endautoescape %}