diff --git a/ietf/iesg/views.py b/ietf/iesg/views.py index 1867a8bf1..1f7df399e 100644 --- a/ietf/iesg/views.py +++ b/ietf/iesg/views.py @@ -208,6 +208,19 @@ def get_doc_sectionREDESIGN(id): s = s + "1" return s +def get_wg_section(wg): + if wg.state_id == "proposed": + if wg.charter.charter_state_id == "intrev": + s = '411' + elif wg.charter.charter_state_id == "iesgrev": + s = '412' + elif wg.state_id == "active": + if wg.charter.charter_state_id == "intrev": + s = '421' + elif wg.charter.charter_state_id == "iesgrev": + s = '422' + return s + if settings.USE_DB_REDESIGN_PROXY_CLASSES: get_doc_section = get_doc_sectionREDESIGN @@ -253,15 +266,17 @@ def agenda_docs(date, next_agenda): return res def agenda_wg_actions(date): - mapping = {12:'411', 13:'412',22:'421',23:'422'} - matches = WGAction.objects.filter(agenda=1,telechat_date=date,category__in=mapping.keys()).order_by('category') - res = {} - for o in matches: - section_key = "s"+mapping[o.category] + from doc.models import TelechatDocEvent + from group.models import Group + + matches = Group.objects.filter(charter__docevent__telechatdocevent__telechat_date=date) + + res = dict(("s%s%s%s" % (i, j, k), []) for i in range(2, 5) for j in range (1, 4) for k in range(1, 4)) + for wg in list(matches): + section_key = "s"+get_wg_section(wg) if section_key not in res: res[section_key] = [] - area = AreaGroup.objects.get(group=o.group_acronym) - res[section_key].append({'obj':o, 'area':str(area.area)}) + res[section_key].append({'obj':wg}) return res def agenda_management_issues(date): diff --git a/ietf/templates/iesg/agenda_wg.html b/ietf/templates/iesg/agenda_wg.html index 9d6edc402..1d7025a70 100644 --- a/ietf/templates/iesg/agenda_wg.html +++ b/ietf/templates/iesg/agenda_wg.html @@ -43,20 +43,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. {% endif %} -{{wg.area|upper}} -{{ wg.obj.status_date|date:"M d"}} +{{wg.obj.parent.name|upper}} +{{ wg.obj.time|date:"M d"}} - -{{ wg.obj.group_acronym.name|escape }} ({{wg.obj.group_acronym}}) + +{{ wg.obj.name|escape }} ({{wg.obj.acronym}}) -{% if wg.obj.token_name %} -Token:{{ wg.obj.token_name|escape }} -{% endif %} -{% if wg.obj.note %} -Note: {{wg.obj.note|escape}} -{% endif %} {% if forloop.last %} diff --git a/ietf/templates/iesg/agenda_wg.txt b/ietf/templates/iesg/agenda_wg.txt index fa1d09a62..3d444ec2d 100644 --- a/ietf/templates/iesg/agenda_wg.txt +++ b/ietf/templates/iesg/agenda_wg.txt @@ -35,11 +35,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. {{ title2 }} {% endif %}{{ title3 }} {% for wg in section_wgs %} - o {{ wg.obj.group_acronym.name }} ({{wg.obj.group_acronym}}) -{% if wg.obj.token_name %} Token: {{ wg.obj.token_name }} -{% endif %} -{% if wg.obj.note %} {% filter wordwrap:"68"|indent|indent %}Note: {{wg.obj.note|striptags}}{% endfilter %} -{% endif %} + o {{ wg.obj.name }} ({{wg.obj.acronym}}) {% empty %} NONE {% endfor %} diff --git a/ietf/templates/iesg/moderator_wg.html b/ietf/templates/iesg/moderator_wg.html index 14a4565af..36c02c0ea 100644 --- a/ietf/templates/iesg/moderator_wg.html +++ b/ietf/templates/iesg/moderator_wg.html @@ -36,14 +36,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. {{ title2 }}
{{ title3 }} ({{ forloop.counter }} of {{ section_wgs|length }}) -

{{ wg.obj.group_acronym.name }} ({{wg.obj.group_acronym}})
-{% if wg.obj.token_name %} -Token: {{ wg.obj.token_name }} -{% endif %}

- -{% if wg.obj.note %} -

Note: {{wg.obj.note|striptags}}

-{% endif %} +

{{ wg.obj.name }} ({{wg.obj.acronym}})
{% if title3|startswith:"4.1.1" %}

Does anyone have an objection to the charter being sent for diff --git a/ietf/templates/wgrecord/announcement_text.html b/ietf/templates/wgrecord/announcement_text.html index 843354a83..7d8dde829 100644 --- a/ietf/templates/wgrecord/announcement_text.html +++ b/ietf/templates/wgrecord/announcement_text.html @@ -1,6 +1,6 @@ {% extends "base.html" %} -{% block title %}WG {{ announcement }} announcement writeup for {{ doc.group.acronym }}{% endblock %} +{% block title %}WG {{ announcement }} announcement writeup for {{ charter.chartered_group.acronym }}{% endblock %} {% block morecss %} form #id_announcement_text { @@ -10,7 +10,7 @@ form #id_announcement_text { {% endblock %} {% block content %} -

WG {{ announcement }} announcement writeup for {{ doc.group.acronym }}

+

WG {{ announcement }} announcement writeup for {{ charter.chartered_group.acronym }}

@@ -22,12 +22,4 @@ form #id_announcement_text {
-{% load ietf_filters %} -{% if user|in_group:"Secretariat" %} -

-{% if can_announce %} -Approve ballot -{% endif %} -

-{% endif %} {% endblock%} diff --git a/ietf/templates/wgrecord/ballot_comment_mail.txt b/ietf/templates/wgrecord/ballot_comment_mail.txt index 582fbd081..748bf328f 100644 --- a/ietf/templates/wgrecord/ballot_comment_mail.txt +++ b/ietf/templates/wgrecord/ballot_comment_mail.txt @@ -1,5 +1,5 @@ {% autoescape off %}{{ ad }} has entered the following ballot position for -{{ doc.filename }}-{{ doc.revision_display }}: {{ pos.name }} +{{ charter.name }}-{{ charter.rev }}: {{ pos.name }} When responding, please keep the subject line intact and reply to all email addresses included in the To and CC lines. (Feel free to cut this diff --git a/ietf/templates/wgrecord/ballot_issued.html b/ietf/templates/wgrecord/ballot_issued.html deleted file mode 100644 index 45a8464e3..000000000 --- a/ietf/templates/wgrecord/ballot_issued.html +++ /dev/null @@ -1,13 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Ballot for {{ doc }} issued{% endblock %} - -{% block content %} -

Ballot for {{ doc }} issued

- -

Ballot has been sent out.

- -
- Back to document -
-{% endblock %} diff --git a/ietf/templates/wgrecord/ballot_writeupnotes.html b/ietf/templates/wgrecord/ballot_writeupnotes.html deleted file mode 100644 index 3cab31e74..000000000 --- a/ietf/templates/wgrecord/ballot_writeupnotes.html +++ /dev/null @@ -1,36 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Ballot writeup and notes for {{ doc }}{% endblock %} - -{% block morecss %} -form #id_ballot_writeup { - width: 700px; - height: 600px; -} -{% endblock %} - -{% block content %} -

Ballot writeup and notes for {{ doc }}

- - -
- -

(Technical Summary, Working Group Summary, Document Quality, - Personnel, RFC Editor Note, IRTF Note, IESG Note, IANA Note)

- -

This text will be appended to all announcements and messages to - the IRTF or RFC Editor.

- - {{ ballot_writeup_form.ballot_writeup }} - - {% if not approval %}

Ballot cannot be issued before announcement text is added.

{% endif %} - -
- Back - - -
-
- - -{% endblock%} diff --git a/ietf/templates/wgrecord/edit_position.html b/ietf/templates/wgrecord/edit_position.html index 64e00439c..e9609ef27 100644 --- a/ietf/templates/wgrecord/edit_position.html +++ b/ietf/templates/wgrecord/edit_position.html @@ -3,10 +3,6 @@ {% block title %}Change position for {{ ad.name }} on {{ wg.acronym }}{% endblock %} {% block morecss %} -div.ballot-deferred { - margin-top: 8px; - margin-bottom: 8px; -} form.position-form .position ul { padding: 0; margin: 0; diff --git a/ietf/templates/wgrecord/record_ballot.html b/ietf/templates/wgrecord/record_ballot.html index 5a32b29ba..d3debdcd8 100644 --- a/ietf/templates/wgrecord/record_ballot.html +++ b/ietf/templates/wgrecord/record_ballot.html @@ -40,7 +40,7 @@ Copyright The IETF Trust 2011, All Rights Reserved {% for pos in info.positions %} {% if pos.comment or pos.block_comment %} -

{% if pos.is_old_ad %}[{%endif%}{{pos.ad|escape}}{% if pos.is_old_ad %}]{%endif%}

+

{{pos.ad|escape}}

{% if pos.block_comment %}

Blocking ({{pos.block_comment_time}})

diff --git a/ietf/templates/wgrecord/record_ballot_list.html b/ietf/templates/wgrecord/record_ballot_list.html index db513edb2..3d5afb9bb 100644 --- a/ietf/templates/wgrecord/record_ballot_list.html +++ b/ietf/templates/wgrecord/record_ballot_list.html @@ -1,7 +1,6 @@ {% load ietf_filters %} {% for p in positions %} -{% if p.is_old_ad %}[{%endif%}{{p.ad}}{% if p.is_old_ad %}]{%endif%}{% if p.comment or p.block_comment %} *{% endif %}
-{% if p.old_positions %}(was {{p.old_positions|join:", "}})
{%endif%} +{{p.ad}}{% if p.comment or p.block_comment %} *{% endif %}
{% empty %} none {% endfor %} diff --git a/ietf/templates/wgrecord/record_history.html b/ietf/templates/wgrecord/record_history.html index 7f586fb14..69c06b6b2 100644 --- a/ietf/templates/wgrecord/record_history.html +++ b/ietf/templates/wgrecord/record_history.html @@ -29,12 +29,8 @@ Copyright The IETF Trust 2011, All Rights Reserved {{ c.info.text|fill:"80"|safe|urlize|linebreaksbr|keep_spacing|sanitize_html|safe }} {% else %} -{% if c.info.dontmolest %} -{{ c.info.text|safe }} -{% else %} {{ c.info.text|fill:"80"|safe|urlize|linebreaksbr|keep_spacing|sanitize_html|safe }} {% endif %} -{% endif %} {% endif %} diff --git a/ietf/templates/wgrecord/record_main.html b/ietf/templates/wgrecord/record_main.html index e7ba324b2..7b52cd1b0 100644 --- a/ietf/templates/wgrecord/record_main.html +++ b/ietf/templates/wgrecord/record_main.html @@ -26,9 +26,7 @@ div.diffTool { padding: 8px 4px; margin: 8px 0;} {% endblock %} {% block pagehead %} -{% if doc.in_ietf_process %} - -{% endif %} + {% endblock %} diff --git a/ietf/templates/wgrecord/send_ballot_comment.html b/ietf/templates/wgrecord/send_ballot_comment.html index 631cefebb..9539494f5 100644 --- a/ietf/templates/wgrecord/send_ballot_comment.html +++ b/ietf/templates/wgrecord/send_ballot_comment.html @@ -21,14 +21,7 @@ form.send-ballot pre { Cc:
separated
by comma
-
- {% if doc.idinternal.state_change_notice_to %} - - {% endif %} - + Subject: {{ subject }} diff --git a/ietf/templates/wgrecord/submit.html b/ietf/templates/wgrecord/submit.html index 166994c6b..9935a1c13 100644 --- a/ietf/templates/wgrecord/submit.html +++ b/ietf/templates/wgrecord/submit.html @@ -4,27 +4,9 @@ Charter submission for {{ wg.acronym }} {% endblock %} -{% block morecss %} -.ietf-navset { - background:#214197 url(/images/yui/sprite.png) repeat-x left -1400px; - color:white; - border:1px solid black; - padding:4px; -} -.ietf-navset .selected { font-weight:bold; padding: 0 3px; } -.ietf-navset a, .ietf-navset a:visited { color: white; padding:0 3px; } -.cutoff-warning { border: 1px dashed red; background-color: #ffeeaa; padding: 1em 2em; margin: 1em 0px; } -{% endblock %} - {% block content %}

Charter submission for {{ wg.acronym }}

-{% if form.cutoff_warning %} -
-{{ form.cutoff_warning|safe }} -
-{% endif %} -

The text will be submitted as charter-ietf-{{ wg.acronym }}-{{ next_rev }}

diff --git a/ietf/templates/wgrecord/wg_description.html b/ietf/templates/wgrecord/wg_description.html index d91c0402c..3084834d0 100644 --- a/ietf/templates/wgrecord/wg_description.html +++ b/ietf/templates/wgrecord/wg_description.html @@ -1 +1 @@ -FIXME: description of {{ wg.name }} +IETF Working Group {{ wg.name }} ({{ wg.acronym }}){% if wg.parent %} under the {{ wg.parent }}{% endif %} diff --git a/ietf/wgrecord/tests.py b/ietf/wgrecord/tests.py index 5c877b14f..c6076ebce 100644 --- a/ietf/wgrecord/tests.py +++ b/ietf/wgrecord/tests.py @@ -359,3 +359,296 @@ class WgInfoTestCase(django.test.TestCase): self.assertEquals(charter.rev, next_revision(prev_rev)) self.assertTrue("new_revision" in charter.latest_event().type) +class WgAddCommentTestCase(django.test.TestCase): + fixtures = ['names'] + + def test_add_comment(self): + make_test_data() + # Make sure all relevant names are created + type_charter = name(DocTypeName, "charter", "Charter") + active = name(GroupStateName, "active", "Active") + notrev=name(CharterDocStateName, slug="notrev", name="Not currently under review") + infrev=name(CharterDocStateName, slug="infrev", name="Informal IESG review") + intrev=name(CharterDocStateName, slug="intrev", name="Internal review") + extrev=name(CharterDocStateName, slug="extrev", name="External review") + iesgrev=name(CharterDocStateName, slug="iesgrev", name="IESG review") + approved=name(CharterDocStateName, slug="approved", name="Approved") + + group = Group.objects.get(acronym="mars") + url = urlreverse('wg_add_comment', kwargs=dict(name=group.acronym)) + login_testing_unauthorized(self, "secretary", url) + + # normal get + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + q = PyQuery(r.content) + self.assertEquals(len(q('form textarea[name=comment]')), 1) + + # request resurrect + comments_before = group.groupevent_set.filter(type="added_comment").count() + + r = self.client.post(url, dict(comment="This is a test.")) + self.assertEquals(r.status_code, 302) + + self.assertEquals(group.groupevent_set.filter(type="added_comment").count(), comments_before + 1) + self.assertTrue("This is a test." in group.groupevent_set.filter(type="added_comment").order_by('-time')[0].desc) + +class WgEditPositionTestCase(django.test.TestCase): + fixtures = ['names', 'ballot'] + + def test_edit_position(self): + make_test_data() + # Make sure all relevant names are created + type_charter = name(DocTypeName, "charter", "Charter") + active = name(GroupStateName, "active", "Active") + notrev=name(CharterDocStateName, slug="notrev", name="Not currently under review") + infrev=name(CharterDocStateName, slug="infrev", name="Informal IESG review") + intrev=name(CharterDocStateName, slug="intrev", name="Internal review") + extrev=name(CharterDocStateName, slug="extrev", name="External review") + iesgrev=name(CharterDocStateName, slug="iesgrev", name="IESG review") + approved=name(CharterDocStateName, slug="approved", name="Approved") + no = name(GroupBallotPositionName, 'no', 'No'), + yes = name(GroupBallotPositionName, 'yes', 'Yes'), + abstain = name(GroupBallotPositionName, 'abstain', 'Abstain'), + block = name(GroupBallotPositionName, 'block', 'Block'), + norecord = name(GroupBallotPositionName, 'norecord', 'No record'), + + group = Group.objects.get(acronym="mars") + url = urlreverse('wg_edit_position', kwargs=dict(name=group.acronym)) + login_testing_unauthorized(self, "ad", url) + + charter = set_or_create_charter(group) + + p = Person.objects.get(name="Aread Irector") + + e = DocEvent() + e.type = "started_iesg_process" + e.by = p + e.doc = charter + e.desc = "IESG process started" + e.save() + + charter.charter_state = iesgrev + charter.save() + + # normal get + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + q = PyQuery(r.content) + self.assertTrue(len(q('form input[name=position]')) > 0) + self.assertEquals(len(q('form textarea[name=comment]')), 1) + + # vote + pos_before = charter.docevent_set.filter(type="changed_ballot_position").count() + self.assertTrue(not charter.docevent_set.filter(type="changed_ballot_position", by__name="Aread Irector")) + + r = self.client.post(url, dict(position="block", + block_comment="This is a blocking test.", + comment="This is a test.")) + self.assertEquals(r.status_code, 302) + + self.assertEquals(charter.docevent_set.filter(type="changed_ballot_position").count(), pos_before + 1) + e = charter.latest_event(GroupBallotPositionDocEvent) + self.assertTrue("This is a blocking test." in e.block_comment) + self.assertTrue("This is a test." in e.comment) + self.assertTrue(e.pos_id, "block") + + # recast vote + pos_before = charter.docevent_set.filter(type="changed_ballot_position").count() + + r = self.client.post(url, dict(position="yes")) + self.assertEquals(r.status_code, 302) + + self.assertEquals(charter.docevent_set.filter(type="changed_ballot_position").count(), pos_before + 1) + e = charter.latest_event(GroupBallotPositionDocEvent) + self.assertTrue(e.pos_id, "yes") + + # clear vote + pos_before = charter.docevent_set.filter(type="changed_ballot_position").count() + + r = self.client.post(url, dict(position="norecord")) + self.assertEquals(r.status_code, 302) + + self.assertEquals(charter.docevent_set.filter(type="changed_ballot_position").count(), pos_before + 1) + e = charter.latest_event(GroupBallotPositionDocEvent) + self.assertTrue(e.pos_id, "norecord") + + def test_edit_position_as_secretary(self): + make_test_data() + # Make sure all relevant names are created + type_charter = name(DocTypeName, "charter", "Charter") + active = name(GroupStateName, "active", "Active") + notrev=name(CharterDocStateName, slug="notrev", name="Not currently under review") + infrev=name(CharterDocStateName, slug="infrev", name="Informal IESG review") + intrev=name(CharterDocStateName, slug="intrev", name="Internal review") + extrev=name(CharterDocStateName, slug="extrev", name="External review") + iesgrev=name(CharterDocStateName, slug="iesgrev", name="IESG review") + approved=name(CharterDocStateName, slug="approved", name="Approved") + no = name(GroupBallotPositionName, 'no', 'No'), + yes = name(GroupBallotPositionName, 'yes', 'Yes'), + abstain = name(GroupBallotPositionName, 'abstain', 'Abstain'), + block = name(GroupBallotPositionName, 'block', 'Block'), + norecord = name(GroupBallotPositionName, 'norecord', 'No record'), + + group = Group.objects.get(acronym="mars") + url = urlreverse('wg_edit_position', kwargs=dict(name=group.acronym)) + p = Person.objects.get(name="Aread Irector") + url += "?ad=%d" % p.id + login_testing_unauthorized(self, "secretary", url) + + charter = set_or_create_charter(group) + + e = DocEvent() + e.type = "started_iesg_process" + e.by = p + e.doc = charter + e.desc = "IESG process started" + e.save() + + charter.charter_state = iesgrev + charter.save() + + # normal get + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + q = PyQuery(r.content) + self.assertTrue(len(q('form input[name=position]')) > 0) + + # vote for rhousley + pos_before = charter.docevent_set.filter(type="changed_ballot_position").count() + self.assertTrue(not charter.docevent_set.filter(type="changed_ballot_position", by__name="Sec Retary")) + + r = self.client.post(url, dict(position="no")) + self.assertEquals(r.status_code, 302) + + self.assertEquals(charter.docevent_set.filter(type="changed_ballot_position").count(), pos_before + 1) + e = charter.latest_event(GroupBallotPositionDocEvent) + self.assertTrue(e.pos_id, "no") + + def test_send_ballot_comment(self): + make_test_data() + # Make sure all relevant names are created + type_charter = name(DocTypeName, "charter", "Charter") + active = name(GroupStateName, "active", "Active") + notrev=name(CharterDocStateName, slug="notrev", name="Not currently under review") + infrev=name(CharterDocStateName, slug="infrev", name="Informal IESG review") + intrev=name(CharterDocStateName, slug="intrev", name="Internal review") + extrev=name(CharterDocStateName, slug="extrev", name="External review") + iesgrev=name(CharterDocStateName, slug="iesgrev", name="IESG review") + approved=name(CharterDocStateName, slug="approved", name="Approved") + no = name(GroupBallotPositionName, 'no', 'No'), + yes = name(GroupBallotPositionName, 'yes', 'Yes'), + abstain = name(GroupBallotPositionName, 'abstain', 'Abstain'), + block = name(GroupBallotPositionName, 'block', 'Block'), + norecord = name(GroupBallotPositionName, 'norecord', 'No record'), + + group = Group.objects.get(acronym="mars") + url = urlreverse('wg_send_ballot_comment', kwargs=dict(name=group.acronym)) + login_testing_unauthorized(self, "ad", url) + + charter = set_or_create_charter(group) + + p = Person.objects.get(name="Aread Irector") + + e = DocEvent() + e.type = "started_iesg_process" + e.by = p + e.doc = charter + e.desc = "IESG process started" + e.save() + + charter.charter_state = iesgrev + charter.save() + + GroupBallotPositionDocEvent.objects.create( + doc=charter, + by=p, + type="changed_ballot_position", + pos=GroupBallotPositionName.objects.get(slug="block"), + ad=p, + block_comment="This is a block test", + comment="This is a test", + ) + + # normal get + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + q = PyQuery(r.content) + self.assertTrue(len(q('form input[name="cc"]')) > 0) + + # send + p = Person.objects.get(name="Aread Irector") + mailbox_before = len(mail_outbox) + + r = self.client.post(url, dict(cc="test@example.com", cc_state_change="1")) + self.assertEquals(r.status_code, 302) + + self.assertEquals(len(mail_outbox), mailbox_before + 1) + self.assertTrue("BLOCKING COMMENT" in mail_outbox[-1]['Subject']) + self.assertTrue("COMMENT" in mail_outbox[-1]['Subject']) + +class WgApproveBallotTestCase(django.test.TestCase): + fixtures = ['base', 'names', 'ballot'] + + def test_approve_ballot(self): + make_test_data() + # Make sure all relevant names are created + type_charter = name(DocTypeName, "charter", "Charter") + proposed = name(GroupStateName, "proposed", "Proposed") + active = name(GroupStateName, "active", "Active") + notrev=name(CharterDocStateName, slug="notrev", name="Not currently under review") + infrev=name(CharterDocStateName, slug="infrev", name="Informal IESG review") + intrev=name(CharterDocStateName, slug="intrev", name="Internal review") + extrev=name(CharterDocStateName, slug="extrev", name="External review") + iesgrev=name(CharterDocStateName, slug="iesgrev", name="IESG review") + approved=name(CharterDocStateName, slug="approved", name="Approved") + no = name(GroupBallotPositionName, 'no', 'No'), + yes = name(GroupBallotPositionName, 'yes', 'Yes'), + abstain = name(GroupBallotPositionName, 'abstain', 'Abstain'), + block = name(GroupBallotPositionName, 'block', 'Block'), + norecord = name(GroupBallotPositionName, 'norecord', 'No record'), + + group = Group.objects.get(acronym="mars") + url = urlreverse('wg_approve_ballot', kwargs=dict(name=group.acronym)) + login_testing_unauthorized(self, "secretary", url) + + charter = set_or_create_charter(group) + + p = Person.objects.get(name="Aread Irector") + + e = DocEvent() + e.type = "started_iesg_process" + e.by = p + e.doc = charter + e.desc = "IESG process started" + e.save() + + charter.charter_state = iesgrev + charter.save() + + # normal get + r = self.client.get(url) + self.assertEquals(r.status_code, 200) + q = PyQuery(r.content) + self.assertTrue("Send out the announcement" in q('input[type=submit]')[0].get('value')) + self.assertEquals(len(q('pre')), 1) + + # approve + mailbox_before = len(mail_outbox) + + # Dont copy the actual txt file + from django.conf import settings + settings.DONT_COPY_CHARTER_ON_APPROVE = True + + r = self.client.post(url, dict()) + self.assertEquals(r.status_code, 302) + + charter = Document.objects.get(name=charter.name) + self.assertEquals(charter.charter_state_id, "approved") + + self.assertEquals(charter.rev, "01") + + self.assertEquals(len(mail_outbox), mailbox_before + 2) + + self.assertTrue("WG Action" in mail_outbox[-1]['Subject']) + self.assertTrue("Charter approved" in mail_outbox[-2]['Subject']) diff --git a/ietf/wgrecord/urls.py b/ietf/wgrecord/urls.py index d42a72dcd..3be2f76f2 100644 --- a/ietf/wgrecord/urls.py +++ b/ietf/wgrecord/urls.py @@ -14,16 +14,16 @@ urlpatterns += patterns('', (r'^searchPerson/$', views_search.search_person), url(r'^ad/(?P[A-Za-z0-9.-]+)/$', views_search.by_ad, name="wg_search_by_ad"), url(r'^in_process/$', views_search.in_process, name="wg_search_in_process"), - url(r'^(?P[A-Za-z0-9._-]+)/((?P[0-9][0-9](-[0-9][0-9])?)/)?((?Pballot|writeup|history)/)?$', views_rec.wg_main, name="wg_view_record"), - (r'^(?P[A-Za-z0-9._-]+)/_ballot.data$', views_rec.wg_ballot), - url(r'^(?P[A-Za-z0-9._-]+)/edit/state/$', views_edit.change_state, name='wg_change_state'), - url(r'^(?P[A-Za-z0-9._-]+)/edit/info/$', views_edit.edit_info, name='wg_edit_info'), - url(r'^(?P[A-Za-z0-9._-]+)/edit/conclude/$', views_edit.conclude, name='wg_conclude'), - url(r'^(?P[A-Za-z0-9._-]+)/edit/addcomment/$', views_edit.add_comment, name='wg_add_comment'), - url(r'^(?P[A-Za-z0-9._-]+)/edit/(?Paction|review)/$', views_ballot.announcement_text, name='wg_announcement_text'), - url(r'^(?P[A-Za-z0-9._-]+)/edit/position/$', views_ballot.edit_position, name='wg_edit_position'), - url(r'^(?P[A-Za-z0-9._-]+)/edit/sendballotcomment/$', views_ballot.send_ballot_comment, name='wg_send_ballot_comment'), - url(r'^(?P[A-Za-z0-9._-]+)/edit/approveballot/$', views_ballot.approve_ballot, name='wg_approve_ballot'), - url(r'^(?P[A-Za-z0-9._-]+)/submit/$', views_submit.submit, name='wg_submit'), + url(r'^(?P[A-Za-z0-9._+-]+)/((?P[0-9][0-9](-[0-9][0-9])?)/)?((?Pballot|writeup|history)/)?$', views_rec.wg_main, name="wg_view_record"), + (r'^(?P[A-Za-z0-9._+-]+)/_ballot.data$', views_rec.wg_ballot), + url(r'^(?P[A-Za-z0-9._+-]+)/edit/state/$', views_edit.change_state, name='wg_change_state'), + url(r'^(?P[A-Za-z0-9._+-]+)/edit/info/$', views_edit.edit_info, name='wg_edit_info'), + url(r'^(?P[A-Za-z0-9._+-]+)/edit/conclude/$', views_edit.conclude, name='wg_conclude'), + url(r'^(?P[A-Za-z0-9._+-]+)/edit/addcomment/$', views_edit.add_comment, name='wg_add_comment'), + url(r'^(?P[A-Za-z0-9._+-]+)/edit/(?Paction|review)/$', views_ballot.announcement_text, name='wg_announcement_text'), + url(r'^(?P[A-Za-z0-9._+-]+)/edit/position/$', views_ballot.edit_position, name='wg_edit_position'), + url(r'^(?P[A-Za-z0-9._+-]+)/edit/sendballotcomment/$', views_ballot.send_ballot_comment, name='wg_send_ballot_comment'), + url(r'^(?P[A-Za-z0-9._+-]+)/edit/approveballot/$', views_ballot.approve_ballot, name='wg_approve_ballot'), + url(r'^(?P[A-Za-z0-9._+-]+)/submit/$', views_submit.submit, name='wg_submit'), ) diff --git a/ietf/wgrecord/views_ballot.py b/ietf/wgrecord/views_ballot.py index 43f2ad20d..45766a835 100644 --- a/ietf/wgrecord/views_ballot.py +++ b/ietf/wgrecord/views_ballot.py @@ -24,12 +24,14 @@ from group.models import Group, GroupHistory, GroupEvent, save_group_in_history from name.models import GroupBallotPositionName, CharterDocStateName, GroupStateName from doc.models import Document, DocEvent, GroupBallotPositionDocEvent, WriteupDocEvent -def default_action_text(wg, doc, user): - e = WriteupDocEvent(doc=doc, by=user) +def default_action_text(wg, charter, user): + e = WriteupDocEvent(doc=charter, by=user) e.by = user e.type = "changed_action_announcement" e.desc = "WG action text was changed" - e.text = "The %s (%s) working group " % (wg.name, wg.acronym) + e.text = "To: ietf-announce@ietf.org\n" + e.text += "Subject: WG Action: %s (%s)\n" % (wg.name, wg.acronym) + e.text += "The %s (%s) working group " % (wg.name, wg.acronym) if wg.parent: e.text += "in the %s " % wg.parent.name e.text += "of the IETF has been " @@ -41,15 +43,17 @@ def default_action_text(wg, doc, user): e.save() return e -def default_review_text(wg, doc, user): - e = WriteupDocEvent(doc=doc, by=user) +def default_review_text(wg, charter, user): + e = WriteupDocEvent(doc=charter, by=user) e.by = user e.type = "changed_review_announcement" e.desc = "WG review text was changed" + e.text = "To: ietf-announce@ietf.org\n" + e.text += "Subject: WG Review: %s (%s)\n" % (wg.name, wg.acronym) if wg.state_id == "proposed": - e.text = "A charter" + e.text += "A charter" else: - e.text = "A modified charter" + e.text += "A modified charter" e.text += " has been submitted for the %s (%s) working group \n" % (wg.name, wg.acronym) if wg.parent: e.text += "in the %s " % wg.parent.name @@ -100,15 +104,17 @@ def edit_position(request, name): else: raise Http404 - doc = set_or_create_charter(wg) - started_process = doc.latest_event(type="started_iesg_process") + charter = set_or_create_charter(wg) + started_process = charter.latest_event(type="started_iesg_process") + if not started_process: + raise Http404 ad = login = request.user.get_profile() if 'HTTP_REFERER' in request.META: return_to_url = request.META['HTTP_REFERER'] else: - return_to_url = doc.get_absolute_url() + return_to_url = charter.get_absolute_url() # if we're in the Secretariat, we can select an AD to act as stand-in for if not has_role(request.user, "Area Director"): @@ -118,7 +124,7 @@ def edit_position(request, name): from person.models import Person ad = get_object_or_404(Person, pk=ad_id) - old_pos = doc.latest_event(GroupBallotPositionDocEvent, type="changed_ballot_position", ad=ad, time__gte=started_process.time) + old_pos = charter.latest_event(GroupBallotPositionDocEvent, type="changed_ballot_position", ad=ad, time__gte=started_process.time) if request.method == 'POST': form = EditPositionForm(request.POST) @@ -130,7 +136,7 @@ def edit_position(request, name): if clean['return_to_url']: return_to_url = clean['return_to_url'] - pos = GroupBallotPositionDocEvent(doc=doc, by=login) + pos = GroupBallotPositionDocEvent(doc=charter, by=login) pos.type = "changed_ballot_position" pos.ad = ad pos.pos = clean["position"] @@ -149,7 +155,7 @@ def edit_position(request, name): changes.append("comment") if pos.comment: - e = DocEvent(doc=doc) + e = DocEvent(doc=charter) e.by = ad # otherwise we can't see who's saying it e.type = "added_comment" e.desc = "[Ballot comment]\n" + pos.comment @@ -161,7 +167,7 @@ def edit_position(request, name): changes.append("block_comment") if pos.block_comment: - e = DocEvent(doc=doc, by=login) + e = DocEvent(doc=charter, by=login) e.by = ad # otherwise we can't see who's saying it e.type = "added_comment" e.desc = "[Ballot blocking comment]\n" + pos.block_comment @@ -186,8 +192,8 @@ def edit_position(request, name): for e in added_events: e.save() # save them after the position is saved to get later id - doc.time = pos.time - doc.save() + charter.time = pos.time + charter.save() if request.POST.get("send_mail"): qstr = "?return_to_url=%s" % return_to_url @@ -209,7 +215,7 @@ def edit_position(request, name): form = EditPositionForm(initial=initial) return render_to_response('wgrecord/edit_position.html', - dict(doc=doc, + dict(charter=charter, wg=wg, form=form, ad=ad, @@ -230,8 +236,8 @@ def send_ballot_comment(request, name): else: raise Http404 - doc = set_or_create_charter(wg) - started_process = doc.latest_event(type="started_iesg_process") + charter = set_or_create_charter(wg) + started_process = charter.latest_event(type="started_iesg_process") if not started_process: raise Http404() @@ -239,12 +245,12 @@ def send_ballot_comment(request, name): return_to_url = request.GET.get('return_to_url') if not return_to_url: - return_to_url = doc.get_absolute_url() + return_to_url = charter.get_absolute_url() if 'HTTP_REFERER' in request.META: back_url = request.META['HTTP_REFERER'] else: - back_url = doc.get_absolute_url() + back_url = charter.get_absolute_url() # if we're in the Secretariat, we can select an AD to act as stand-in for if not has_role(request.user, "Area Director"): @@ -254,7 +260,7 @@ def send_ballot_comment(request, name): from person.models import Person ad = get_object_or_404(Person, pk=ad_id) - pos = doc.latest_event(GroupBallotPositionDocEvent, type="changed_ballot_position", ad=ad, time__gte=started_process.time) + pos = charter.latest_event(GroupBallotPositionDocEvent, type="changed_ballot_position", ad=ad, time__gte=started_process.time) if not pos: raise Http404() @@ -269,28 +275,23 @@ def send_ballot_comment(request, name): subj.append("COMMENT") ad_name_genitive = ad.name + "'" if ad.name.endswith('s') else ad.name + "'s" - subject = "%s %s on %s" % (ad_name_genitive, pos.pos.name if pos.pos else "No Position", doc.name + "-" + doc.rev) + subject = "%s %s on %s" % (ad_name_genitive, pos.pos.name if pos.pos else "No Position", charter.name + "-" + charter.rev) if subj: subject += ": (with %s)" % " and ".join(subj) - doc.filename = doc.name # compatibility attributes - doc.revision_display = doc.rev body = render_to_string("wgrecord/ballot_comment_mail.txt", - dict(block_comment=d, comment=c, ad=ad.name, doc=doc, pos=pos.pos)) + dict(block_comment=d, comment=c, ad=ad.name, charter=charter, pos=pos.pos)) frm = ad.formatted_email() to = "The IESG " if request.method == 'POST': cc = [x.strip() for x in request.POST.get("cc", "").split(',') if x.strip()] - if request.POST.get("cc_state_change") and doc.notify: - cc.extend(doc.notify.split(',')) - send_mail_text(request, to, frm, subject, body, cc=", ".join(cc)) return HttpResponseRedirect(return_to_url) return render_to_response('wgrecord/send_ballot_comment.html', - dict(doc=doc, + dict(charter=charter, subject=subject, body=body, frm=frm, @@ -319,19 +320,19 @@ def announcement_text(request, name, ann): else: raise Http404 - doc = set_or_create_charter(wg) + charter = set_or_create_charter(wg) login = request.user.get_profile() if ann == "action": - existing = doc.latest_event(WriteupDocEvent, type="changed_action_announcement") + existing = charter.latest_event(WriteupDocEvent, type="changed_action_announcement") elif ann == "review": - existing = doc.latest_event(WriteupDocEvent, type="changed_review_announcement") + existing = charter.latest_event(WriteupDocEvent, type="changed_review_announcement") if not existing: if ann == "action": - existing = default_action_text(wg, doc, login) + existing = default_action_text(wg, charter, login) elif ann == "review": - existing = default_review_text(wg, doc, login) + existing = default_review_text(wg, charter, login) form = AnnouncementTextForm(initial=dict(announcement_text=existing.text)) @@ -340,20 +341,20 @@ def announcement_text(request, name, ann): if form.is_valid(): t = form.cleaned_data['announcement_text'] if t != existing.text: - e = WriteupDocEvent(doc=doc, by=login) + e = WriteupDocEvent(doc=charter, by=login) e.by = login e.type = "changed_%s_announcement" % ann e.desc = "WG %s text was changed" % ann e.text = t e.save() - doc.time = e.time - doc.save() + charter.time = e.time + charter.save() return redirect('wg_view_record', name=wg.acronym) return render_to_response('wgrecord/announcement_text.html', - dict(doc=doc, + dict(charter=charter, announcement=ann, - back_url=doc.get_absolute_url(), + back_url=charter.get_absolute_url(), announcement_text_form=form, ), context_instance=RequestContext(request)) @@ -370,13 +371,13 @@ def approve_ballot(request, name): else: raise Http404 - doc = set_or_create_charter(wg) + charter = set_or_create_charter(wg) login = request.user.get_profile() - e = doc.latest_event(WriteupDocEvent, type="changed_action_announcement") + e = charter.latest_event(WriteupDocEvent, type="changed_action_announcement") if not e: - announcement = default_action_text(wg, doc, login) + announcement = default_action_text(wg, charter, login).text else: announcement = e.text @@ -384,15 +385,15 @@ def approve_ballot(request, name): new_state = GroupStateName.objects.get(slug="active") new_charter_state = CharterDocStateName.objects.get(slug="approved") - save_charter_in_history(doc) + save_charter_in_history(charter) save_group_in_history(wg) prev_state = wg.state - prev_charter_state = doc.charter_state + prev_charter_state = charter.charter_state wg.state = new_state - doc.charter_state = new_charter_state + charter.charter_state = new_charter_state - e = DocEvent(doc=doc, by=login) + e = DocEvent(doc=charter, by=login) e.type = "iesg_approved" e.desc = "IESG has approved the charter" @@ -400,36 +401,36 @@ def approve_ballot(request, name): change_description = e.desc + " and WG state has been changed to %s" % new_state.name - e = log_state_changed(request, doc, login, prev_state) + e = log_state_changed(request, charter, login, prev_state) wg.time = e.time wg.save() - filename = os.path.join(doc.get_file_path(), doc.name+"-"+doc.rev+".txt") - try: - source = open(filename, 'rb') - raw_content = source.read() + filename = os.path.join(charter.get_file_path(), charter.name+"-"+charter.rev+".txt") + if not settings.DONT_COPY_CHARTER_ON_APPROVE: + try: + source = open(filename, 'rb') + raw_content = source.read() - doc.rev = next_approved_revision(doc.rev) - - new_filename = os.path.join(doc.get_file_path(), doc.name+"-"+doc.rev+".txt") - destination = open(new_filename, 'wb+') - destination.write(raw_content) - destination.close() - except IOError: - raise Http404 + new_filename = os.path.join(charter.get_file_path(), charter.name+"-"+charter.rev+".txt") + destination = open(new_filename, 'wb+') + destination.write(raw_content) + destination.close() + except IOError: + raise Http404 - doc.save() + charter.rev = next_approved_revision(charter.rev) + charter.save() - email_secretariat(request, wg, "state-%s" % doc.charter_state_id, change_description) + email_secretariat(request, wg, "state-%s" % charter.charter_state_id, change_description) # send announcement send_mail_preformatted(request, announcement) - return HttpResponseRedirect(doc.get_absolute_url()) + return HttpResponseRedirect(charter.get_absolute_url()) return render_to_response('wgrecord/approve_ballot.html', - dict(doc=doc, + dict(charter=charter, announcement=announcement, wg=wg), context_instance=RequestContext(request)) diff --git a/ietf/wgrecord/views_edit.py b/ietf/wgrecord/views_edit.py index 96d5c52f9..35158a2c3 100644 --- a/ietf/wgrecord/views_edit.py +++ b/ietf/wgrecord/views_edit.py @@ -108,7 +108,7 @@ def change_state(request, name): if charter.charter_state_id == "extrev": email_secretariat(request, wg, "state-%s" % charter.charter_state_id, messages['extrev']) - if form.cleaned_data["charter_state"] == "infrev": + if form.cleaned_data["charter_state"].slug == "infrev": e = DocEvent() e.type = "started_iesg_process" e.by = login diff --git a/ietf/wgrecord/views_rec.py b/ietf/wgrecord/views_rec.py index cc81b8267..2a664358a 100644 --- a/ietf/wgrecord/views_rec.py +++ b/ietf/wgrecord/views_rec.py @@ -100,7 +100,7 @@ def wg_main(request, name, rev, tab): info['pos_no'] = filter(lambda x: x.pos_id == "no", latest_positions) info['pos_block'] = filter(lambda x: x.pos_id == "block", latest_positions) info['pos_abstain'] = filter(lambda x: x.pos_id == "abstain", latest_positions) - info['pos_no_record'] = no_record + info['pos_no_record'] = no_record + [x.ad for x in latest_positions if x.pos_id == "norecord"] # Get annoucement texts review_ann = wg.charter.latest_event(WriteupDocEvent, type="changed_review_announcement") diff --git a/redesign/importing/import-groups.py b/redesign/importing/import-groups.py index 54275bc8d..e467e6c95 100755 --- a/redesign/importing/import-groups.py +++ b/redesign/importing/import-groups.py @@ -77,6 +77,13 @@ secretariat_group.state = state_names["active"] secretariat_group.type = type_names["ietf"] secretariat_group.save() +# create RSOC for use with roles +rsoc_group, _ = Group.objects.get_or_create(acronym="rsoc") +rsoc_group.name = "RFC Series Oversight Committee" +rsoc_group.state = state_names["active"] +rsoc_group.type = type_names["ietf"] +rsoc_group.save() + system = Person.objects.get(name="(System)") diff --git a/redesign/importing/import-roles.py b/redesign/importing/import-roles.py index cfa9f7741..b28de0dc4 100755 --- a/redesign/importing/import-roles.py +++ b/redesign/importing/import-roles.py @@ -254,14 +254,12 @@ for o in IESGHistory.objects.all().order_by('meeting__start_date', 'pk'): existing = history if history else area h = GroupHistory(group=area, - charter=existing.charter, time=meeting_time, name=existing.name, acronym=existing.acronym, state=existing.state, type=existing.type, parent=existing.parent, - iesg_state=existing.iesg_state, ad=existing.ad, list_email=existing.list_email, list_subscribe=existing.list_subscribe, diff --git a/static/js/wg-change-state.js b/static/js/wg-change-state.js index 49673cc1e..77d4304e6 100644 --- a/static/js/wg-change-state.js +++ b/static/js/wg-change-state.js @@ -5,8 +5,11 @@ jQuery(document).ready(function () { } function setMessageDraft(state) { - if (jQuery("#id_state").val() != "conclude") { - if (message[state]) { + if (jQuery("#id_state").val() == "conclude") { + jQuery("#id_message").val(""); + initial_time.hide(); + } else { + if (message[state]) { if (state == "infrev") { initial_time.show(); jQuery("#id_initial_time").val(1); @@ -15,11 +18,10 @@ jQuery(document).ready(function () { jQuery("#id_initial_time").val(0); } jQuery("#id_message").val(message[state]); - } else { - jQuery("#id_message").val(""); - } - } else { + } else { jQuery("#id_message").val(""); + initial_time.hide(); + } } } @@ -27,6 +29,10 @@ jQuery(document).ready(function () { setMessageDraft(jQuery(this).val()); }); + jQuery("#id_state").click(function (e) { + setMessageDraft(jQuery("#id_charter_state").val()); + }); + jQuery("#id_charter_state").click(); });