DocumentAuthor, rename author field to email and make it optional (for modeling old email-less submissions), remove the authors many to many referencing field from Document as it is not really pointing the right place. Update the Secretariat tools to show affiliation and country. Add migration for getting rid of the fake email addresses that the migration script created some years ago (just set the author email field to null). - Legacy-Id: 12739
1498 lines
66 KiB
Python
1498 lines
66 KiB
Python
# -*- coding: utf-8 -*-
|
|
import os
|
|
import shutil
|
|
import datetime
|
|
import StringIO
|
|
from pyquery import PyQuery
|
|
|
|
from django.core.urlresolvers import reverse as urlreverse
|
|
from django.conf import settings
|
|
|
|
import debug # pyflakes:ignore
|
|
|
|
from ietf.doc.models import ( Document, DocAlias, DocReminder, DocumentAuthor, DocEvent,
|
|
ConsensusDocEvent, LastCallDocEvent, RelatedDocument, State, TelechatDocEvent,
|
|
WriteupDocEvent, BallotDocEvent, DocRelationshipName)
|
|
from ietf.doc.utils import get_tags_for_stream_id
|
|
from ietf.name.models import StreamName, IntendedStdLevelName, DocTagName
|
|
from ietf.group.models import Group
|
|
from ietf.person.models import Person, Email
|
|
from ietf.meeting.models import Meeting, MeetingTypeName
|
|
from ietf.iesg.models import TelechatDate
|
|
from ietf.utils.test_utils import login_testing_unauthorized, unicontent
|
|
from ietf.utils.test_data import make_test_data
|
|
from ietf.utils.mail import outbox, empty_outbox
|
|
from ietf.utils.test_utils import TestCase
|
|
|
|
|
|
class ChangeStateTests(TestCase):
|
|
def test_ad_approved(self):
|
|
# get a draft in iesg evaluation, point raised
|
|
draft = make_test_data()
|
|
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva"))
|
|
draft.tags.add("point")
|
|
|
|
url = urlreverse('doc_change_state', kwargs=dict(name=draft.name))
|
|
login_testing_unauthorized(self, "ad", url)
|
|
|
|
# normal get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('form select[name=state]')), 1)
|
|
|
|
events_before = draft.docevent_set.count()
|
|
mailbox_before = len(outbox)
|
|
|
|
# set it to approved with no substate
|
|
r = self.client.post(url,
|
|
dict(state=State.objects.get(used=True, type="draft-iesg", slug="approved").pk,
|
|
substate="",
|
|
comment="Test comment"))
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(name=draft.name)
|
|
|
|
# should now be in approved with no substate
|
|
self.assertEqual(draft.get_state_slug("draft-iesg"), "approved")
|
|
self.assertTrue(not draft.tags.filter(slug="approved"))
|
|
self.assertFalse(draft.tags.exists())
|
|
self.assertEqual(draft.docevent_set.count(), events_before + 2)
|
|
self.assertTrue("Test comment" in draft.docevent_set.all()[0].desc)
|
|
self.assertTrue("IESG state changed" in draft.docevent_set.all()[1].desc)
|
|
|
|
# should have sent two emails, the second one to the iesg with approved message
|
|
self.assertEqual(len(outbox), mailbox_before + 2)
|
|
self.assertTrue("Approved: " in outbox[-1]['Subject'])
|
|
self.assertTrue(draft.name in outbox[-1]['Subject'])
|
|
self.assertTrue('iesg@' in outbox[-1]['To'])
|
|
|
|
def test_change_state(self):
|
|
draft = make_test_data()
|
|
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="ad-eval"))
|
|
|
|
url = urlreverse('doc_change_state', kwargs=dict(name=draft.name))
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
first_state = draft.get_state("draft-iesg")
|
|
next_states = first_state.next_states.all()
|
|
|
|
# normal get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('form select[name=state]')), 1)
|
|
|
|
if next_states:
|
|
self.assertEqual(len(q('[type=submit][value="%s"]' % next_states[0].name)), 1)
|
|
|
|
|
|
# faulty post
|
|
r = self.client.post(url, dict(state=State.objects.get(used=True, type="draft", slug="active").pk))
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertTrue(len(q('form .has-error')) > 0)
|
|
draft = Document.objects.get(name=draft.name)
|
|
self.assertEqual(draft.get_state("draft-iesg"), first_state)
|
|
|
|
|
|
# change state
|
|
events_before = draft.docevent_set.count()
|
|
mailbox_before = len(outbox)
|
|
draft.tags.add("ad-f-up")
|
|
|
|
r = self.client.post(url,
|
|
dict(state=State.objects.get(used=True, type="draft-iesg", slug="review-e").pk,
|
|
substate="point",
|
|
comment="Test comment"))
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(name=draft.name)
|
|
self.assertEqual(draft.get_state_slug("draft-iesg"), "review-e")
|
|
self.assertTrue(not draft.tags.filter(slug="ad-f-up"))
|
|
self.assertTrue(draft.tags.filter(slug="point"))
|
|
self.assertEqual(draft.docevent_set.count(), events_before + 2)
|
|
self.assertTrue("Test comment" in draft.docevent_set.all()[0].desc)
|
|
self.assertTrue("IESG state changed" in draft.docevent_set.all()[1].desc)
|
|
self.assertEqual(len(outbox), mailbox_before + 1)
|
|
self.assertTrue("State Update Notice" in outbox[-1]['Subject'])
|
|
self.assertTrue('draft-ietf-mars-test@' in outbox[-1]['To'])
|
|
self.assertTrue('mars-chairs@' in outbox[-1]['To'])
|
|
self.assertTrue('aread@' in outbox[-1]['To'])
|
|
|
|
# check that we got a previous state now
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('form [type=submit][value="%s"]' % first_state.name)), 1)
|
|
|
|
def test_pull_from_rfc_queue(self):
|
|
draft = make_test_data()
|
|
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="rfcqueue"))
|
|
|
|
url = urlreverse('doc_change_state', kwargs=dict(name=draft.name))
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
# change state
|
|
mailbox_before = len(outbox)
|
|
|
|
r = self.client.post(url,
|
|
dict(state=State.objects.get(used=True, type="draft-iesg", slug="review-e").pk,
|
|
substate="",
|
|
comment="Test comment"))
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(name=draft.name)
|
|
self.assertEqual(draft.get_state_slug("draft-iesg"), "review-e")
|
|
|
|
self.assertEqual(len(outbox), mailbox_before + 2)
|
|
|
|
self.assertTrue(draft.name in outbox[-1]['Subject'])
|
|
self.assertTrue("changed state" in outbox[-1]['Subject'])
|
|
self.assertTrue("is no longer" in str(outbox[-1]))
|
|
self.assertTrue("Test comment" in str(outbox[-1]))
|
|
self.assertTrue("rfc-editor@" in outbox[-1]['To'])
|
|
self.assertTrue("iana@" in outbox[-1]['To'])
|
|
|
|
self.assertTrue("ID Tracker State Update Notice:" in outbox[-2]['Subject'])
|
|
self.assertTrue("aread@" in outbox[-2]['To'])
|
|
|
|
|
|
def test_change_iana_state(self):
|
|
draft = make_test_data()
|
|
|
|
first_state = State.objects.get(used=True, type="draft-iana-review", slug="need-rev")
|
|
next_state = State.objects.get(used=True, type="draft-iana-review", slug="ok-noact")
|
|
draft.set_state(first_state)
|
|
|
|
url = urlreverse('doc_change_iana_state', kwargs=dict(name=draft.name, state_type="iana-review"))
|
|
login_testing_unauthorized(self, "iana", url)
|
|
|
|
# normal get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('form select[name=state]')), 1)
|
|
|
|
# faulty post
|
|
r = self.client.post(url, dict(state="foobarbaz"))
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertTrue(len(q('form .has-error')) > 0)
|
|
draft = Document.objects.get(name=draft.name)
|
|
self.assertEqual(draft.get_state("draft-iana-review"), first_state)
|
|
|
|
# change state
|
|
r = self.client.post(url, dict(state=next_state.pk))
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(name=draft.name)
|
|
self.assertEqual(draft.get_state("draft-iana-review"), next_state)
|
|
|
|
def test_request_last_call(self):
|
|
draft = make_test_data()
|
|
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="ad-eval"))
|
|
|
|
self.client.login(username="secretary", password="secretary+password")
|
|
url = urlreverse('doc_change_state', kwargs=dict(name=draft.name))
|
|
|
|
empty_outbox()
|
|
|
|
self.assertTrue(not draft.latest_event(type="changed_ballot_writeup_text"))
|
|
r = self.client.post(url, dict(state=State.objects.get(used=True, type="draft-iesg", slug="lc-req").pk))
|
|
self.assertTrue("Your request to issue" in unicontent(r))
|
|
|
|
# last call text
|
|
e = draft.latest_event(WriteupDocEvent, type="changed_last_call_text")
|
|
self.assertTrue(e)
|
|
self.assertTrue("The IESG has received" in e.text)
|
|
self.assertTrue(draft.title in e.text)
|
|
self.assertTrue(draft.get_absolute_url() in e.text)
|
|
|
|
# approval text
|
|
e = draft.latest_event(WriteupDocEvent, type="changed_ballot_approval_text")
|
|
self.assertTrue(e)
|
|
self.assertTrue("The IESG has approved" in e.text)
|
|
self.assertTrue(draft.title in e.text)
|
|
self.assertTrue(draft.get_absolute_url() in e.text)
|
|
|
|
# ballot writeup
|
|
e = draft.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text")
|
|
self.assertTrue(e)
|
|
self.assertTrue("Technical Summary" in e.text)
|
|
|
|
# mail notice
|
|
self.assertEqual(len(outbox), 2)
|
|
|
|
self.assertTrue("ID Tracker State Update" in outbox[0]['Subject'])
|
|
self.assertTrue("aread@" in outbox[0]['To'])
|
|
|
|
self.assertTrue("Last Call:" in outbox[1]['Subject'])
|
|
self.assertTrue('iesg-secretary@' in outbox[1]['To'])
|
|
self.assertTrue('aread@' in outbox[1]['Cc'])
|
|
|
|
# comment
|
|
self.assertTrue("Last call was requested" in draft.latest_event().desc)
|
|
|
|
|
|
class EditInfoTests(TestCase):
|
|
def test_edit_info(self):
|
|
draft = make_test_data()
|
|
url = urlreverse('doc_edit_info', kwargs=dict(name=draft.name))
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
# normal get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('form select[name=intended_std_level]')), 1)
|
|
|
|
prev_ad = draft.ad
|
|
# faulty post
|
|
r = self.client.post(url, dict(ad="123456789"))
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertTrue(len(q('form .has-error')) > 0)
|
|
draft = Document.objects.get(name=draft.name)
|
|
self.assertEqual(draft.ad, prev_ad)
|
|
|
|
# edit info
|
|
events_before = draft.docevent_set.count()
|
|
mailbox_before = len(outbox)
|
|
|
|
new_ad = Person.objects.get(name="Ad No1")
|
|
|
|
r = self.client.post(url,
|
|
dict(intended_std_level=str(draft.intended_std_level.pk),
|
|
stream=draft.stream_id,
|
|
ad=str(new_ad.pk),
|
|
notify="test@example.com",
|
|
note="New note",
|
|
telechat_date="",
|
|
))
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(name=draft.name)
|
|
self.assertEqual(draft.ad, new_ad)
|
|
self.assertEqual(draft.note, "New note")
|
|
self.assertTrue(not draft.latest_event(TelechatDocEvent, type="scheduled_for_telechat"))
|
|
self.assertEqual(draft.docevent_set.count(), events_before + 3)
|
|
self.assertEqual(len(outbox), mailbox_before + 1)
|
|
self.assertTrue(draft.name in outbox[-1]['Subject'])
|
|
|
|
def test_edit_telechat_date(self):
|
|
draft = make_test_data()
|
|
|
|
url = urlreverse('doc_edit_info', kwargs=dict(name=draft.name))
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
data = dict(intended_std_level=str(draft.intended_std_level_id),
|
|
stream=draft.stream_id,
|
|
ad=str(draft.ad_id),
|
|
notify=draft.notify,
|
|
note="",
|
|
)
|
|
|
|
# get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
# add to telechat
|
|
mailbox_before=len(outbox)
|
|
self.assertTrue(not draft.latest_event(TelechatDocEvent, type="scheduled_for_telechat"))
|
|
data["telechat_date"] = TelechatDate.objects.active()[0].date.isoformat()
|
|
r = self.client.post(url, data)
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(name=draft.name)
|
|
self.assertTrue(draft.latest_event(TelechatDocEvent, type="scheduled_for_telechat"))
|
|
self.assertEqual(draft.latest_event(TelechatDocEvent, type="scheduled_for_telechat").telechat_date, TelechatDate.objects.active()[0].date)
|
|
self.assertEqual(len(outbox),mailbox_before+1)
|
|
self.assertTrue("Telechat update" in outbox[-1]['Subject'])
|
|
self.assertTrue('iesg@' in outbox[-1]['To'])
|
|
self.assertTrue('iesg-secretary@' in outbox[-1]['To'])
|
|
|
|
# change telechat
|
|
mailbox_before=len(outbox)
|
|
data["telechat_date"] = TelechatDate.objects.active()[1].date.isoformat()
|
|
r = self.client.post(url, data)
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(name=draft.name)
|
|
telechat_event = draft.latest_event(TelechatDocEvent, type="scheduled_for_telechat")
|
|
self.assertEqual(telechat_event.telechat_date, TelechatDate.objects.active()[1].date)
|
|
self.assertFalse(telechat_event.returning_item)
|
|
self.assertEqual(len(outbox),mailbox_before+1)
|
|
self.assertTrue("Telechat update" in outbox[-1]['Subject'])
|
|
|
|
# change to a telechat that should cause returning item to be auto-detected
|
|
# First, make it appear that the previous telechat has already passed
|
|
telechat_event.telechat_date = datetime.date.today()-datetime.timedelta(days=7)
|
|
telechat_event.save()
|
|
ballot = draft.latest_event(BallotDocEvent, type="created_ballot")
|
|
ballot.time = telechat_event.telechat_date
|
|
ballot.save()
|
|
|
|
r = self.client.post(url, data)
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(name=draft.name)
|
|
telechat_event = draft.latest_event(TelechatDocEvent, type="scheduled_for_telechat")
|
|
self.assertEqual(telechat_event.telechat_date, TelechatDate.objects.active()[1].date)
|
|
self.assertTrue(telechat_event.returning_item)
|
|
|
|
# remove from agenda
|
|
mailbox_before=len(outbox)
|
|
data["telechat_date"] = ""
|
|
r = self.client.post(url, data)
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(name=draft.name)
|
|
self.assertTrue(not draft.latest_event(TelechatDocEvent, type="scheduled_for_telechat").telechat_date)
|
|
self.assertEqual(len(outbox),mailbox_before+1)
|
|
self.assertTrue("Telechat update" in outbox[-1]['Subject'])
|
|
|
|
def test_start_iesg_process_on_draft(self):
|
|
make_test_data()
|
|
|
|
draft = Document.objects.create(
|
|
name="draft-ietf-mars-test2",
|
|
time=datetime.datetime.now(),
|
|
type_id="draft",
|
|
title="Testing adding a draft",
|
|
stream=None,
|
|
group=Group.objects.get(acronym="mars"),
|
|
abstract="Test test test.",
|
|
rev="01",
|
|
pages=2,
|
|
intended_std_level_id="ps",
|
|
shepherd=None,
|
|
ad=None,
|
|
expires=datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE),
|
|
)
|
|
DocAlias.objects.create(
|
|
document=draft,
|
|
name=draft.name,
|
|
)
|
|
|
|
DocumentAuthor.objects.create(
|
|
document=draft,
|
|
person=Person.objects.get(email__address="aread@ietf.org"),
|
|
email=Email.objects.get(address="aread@ietf.org"),
|
|
country="US",
|
|
affiliation="",
|
|
order=1
|
|
)
|
|
|
|
url = urlreverse('doc_edit_info', kwargs=dict(name=draft.name))
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
# normal get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('form select[name=intended_std_level]')), 1)
|
|
self.assertEqual(None,q('form input[name=notify]')[0].value)
|
|
|
|
# add
|
|
events_before = draft.docevent_set.count()
|
|
mailbox_before = len(outbox)
|
|
|
|
ad = Person.objects.get(name="Areað Irector")
|
|
|
|
r = self.client.post(url,
|
|
dict(intended_std_level=str(draft.intended_std_level_id),
|
|
ad=ad.pk,
|
|
create_in_state=State.objects.get(used=True, type="draft-iesg", slug="watching").pk,
|
|
notify="test@example.com",
|
|
note="This is a note",
|
|
telechat_date="",
|
|
))
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(name=draft.name)
|
|
self.assertEqual(draft.get_state_slug("draft-iesg"), "watching")
|
|
self.assertEqual(draft.ad, ad)
|
|
self.assertEqual(draft.note, "This is a note")
|
|
self.assertTrue(not draft.latest_event(TelechatDocEvent, type="scheduled_for_telechat"))
|
|
self.assertEqual(draft.docevent_set.count(), events_before + 4)
|
|
events = list(draft.docevent_set.order_by('time', 'id'))
|
|
self.assertEqual(events[-4].type, "started_iesg_process")
|
|
self.assertEqual(len(outbox), mailbox_before+1)
|
|
self.assertTrue('IESG processing' in outbox[-1]['Subject'])
|
|
self.assertTrue('draft-ietf-mars-test2@' in outbox[-1]['To'])
|
|
|
|
# Redo, starting in publication requested to make sure WG state is also set
|
|
draft.unset_state('draft-iesg')
|
|
draft.set_state(State.objects.get(type='draft-stream-ietf',slug='writeupw'))
|
|
draft.stream = StreamName.objects.get(slug='ietf')
|
|
draft.save_with_history([DocEvent.objects.create(doc=draft, type="changed_stream", by=Person.objects.get(user__username="secretary"), desc="Test")])
|
|
r = self.client.post(url,
|
|
dict(intended_std_level=str(draft.intended_std_level_id),
|
|
ad=ad.pk,
|
|
create_in_state=State.objects.get(used=True, type="draft-iesg", slug="pub-req").pk,
|
|
notify="test@example.com",
|
|
note="This is a note",
|
|
telechat_date="",
|
|
))
|
|
self.assertEqual(r.status_code, 302)
|
|
draft = Document.objects.get(name=draft.name)
|
|
self.assertEqual(draft.get_state_slug('draft-iesg'),'pub-req')
|
|
self.assertEqual(draft.get_state_slug('draft-stream-ietf'),'sub-pub')
|
|
|
|
def test_edit_consensus(self):
|
|
draft = make_test_data()
|
|
|
|
url = urlreverse('doc_edit_consensus', kwargs=dict(name=draft.name))
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
# get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
# post
|
|
self.assertTrue(not draft.latest_event(ConsensusDocEvent, type="changed_consensus"))
|
|
r = self.client.post(url, dict(consensus="Yes"))
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
self.assertEqual(draft.latest_event(ConsensusDocEvent, type="changed_consensus").consensus, True)
|
|
|
|
# reset
|
|
e = DocEvent(doc=draft,by=Person.objects.get(name="(System)"),type='changed_document')
|
|
e.desc = u"Intended Status changed to <b>%s</b> from %s"% (draft.intended_std_level_id, 'bcp')
|
|
e.save()
|
|
|
|
draft.intended_std_level_id = 'bcp'
|
|
draft.save_with_history([e])
|
|
r = self.client.post(url, dict(consensus="Unknown"))
|
|
self.assertEqual(r.status_code, 403) # BCPs must have a consensus
|
|
|
|
e = DocEvent(doc=draft,by=Person.objects.get(name="(System)"),type='changed_document')
|
|
e.desc = u"Intended Status changed to <b>%s</b> from %s"% (draft.intended_std_level_id, 'inf')
|
|
e.save()
|
|
|
|
draft.intended_std_level_id = 'inf'
|
|
draft.save_with_history([e])
|
|
r = self.client.post(url, dict(consensus="Unknown"))
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
self.assertEqual(draft.latest_event(ConsensusDocEvent, type="changed_consensus").consensus, None)
|
|
|
|
|
|
class ResurrectTests(TestCase):
|
|
def test_request_resurrect(self):
|
|
draft = make_test_data()
|
|
draft.set_state(State.objects.get(used=True, type="draft", slug="expired"))
|
|
|
|
url = urlreverse('doc_request_resurrect', kwargs=dict(name=draft.name))
|
|
|
|
login_testing_unauthorized(self, "ad", url)
|
|
|
|
# normal get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('form [type=submit]')), 1)
|
|
|
|
|
|
# request resurrect
|
|
events_before = draft.docevent_set.count()
|
|
mailbox_before = len(outbox)
|
|
|
|
r = self.client.post(url, dict())
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(name=draft.name)
|
|
self.assertEqual(draft.docevent_set.count(), events_before + 1)
|
|
e = draft.latest_event(type="requested_resurrect")
|
|
self.assertTrue(e)
|
|
self.assertEqual(e.by, Person.objects.get(name="Areað Irector"))
|
|
self.assertTrue("Resurrection" in e.desc)
|
|
self.assertEqual(len(outbox), mailbox_before + 1)
|
|
self.assertTrue("Resurrection" in outbox[-1]['Subject'])
|
|
self.assertTrue('internet-drafts@' in outbox[-1]['To'])
|
|
|
|
def test_resurrect(self):
|
|
draft = make_test_data()
|
|
draft.set_state(State.objects.get(used=True, type="draft", slug="expired"))
|
|
|
|
DocEvent.objects.create(doc=draft,
|
|
type="requested_resurrect",
|
|
by=Person.objects.get(name="Areað Irector"))
|
|
|
|
url = urlreverse('doc_resurrect', kwargs=dict(name=draft.name))
|
|
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
# normal get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('form [type=submit]')), 1)
|
|
|
|
# complete resurrect
|
|
events_before = draft.docevent_set.count()
|
|
mailbox_before = len(outbox)
|
|
|
|
r = self.client.post(url, dict())
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(name=draft.name)
|
|
self.assertEqual(draft.docevent_set.count(), events_before + 1)
|
|
self.assertEqual(draft.latest_event().type, "completed_resurrect")
|
|
self.assertEqual(draft.get_state_slug(), "active")
|
|
self.assertTrue(draft.expires >= datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE - 1))
|
|
self.assertEqual(len(outbox), mailbox_before + 1)
|
|
self.assertTrue('Resurrection Completed' in outbox[-1]['Subject'])
|
|
self.assertTrue('iesg-secretary' in outbox[-1]['To'])
|
|
self.assertTrue('aread' in outbox[-1]['To'])
|
|
|
|
|
|
class ExpireIDsTests(TestCase):
|
|
def setUp(self):
|
|
self.saved_id_dir = settings.INTERNET_DRAFT_PATH
|
|
self.saved_archive_dir = settings.INTERNET_DRAFT_ARCHIVE_DIR
|
|
self.id_dir = os.path.abspath("tmp-id-dir")
|
|
self.archive_dir = os.path.abspath("tmp-id-archive")
|
|
if not os.path.exists(self.id_dir):
|
|
os.mkdir(self.id_dir)
|
|
if not os.path.exists(self.archive_dir):
|
|
os.mkdir(self.archive_dir)
|
|
os.mkdir(os.path.join(self.archive_dir, "unknown_ids"))
|
|
os.mkdir(os.path.join(self.archive_dir, "deleted_tombstones"))
|
|
os.mkdir(os.path.join(self.archive_dir, "expired_without_tombstone"))
|
|
|
|
settings.INTERNET_DRAFT_PATH = self.id_dir
|
|
settings.INTERNET_DRAFT_ARCHIVE_DIR = self.archive_dir
|
|
|
|
def tearDown(self):
|
|
shutil.rmtree(self.id_dir)
|
|
shutil.rmtree(self.archive_dir)
|
|
settings.INTERNET_DRAFT_PATH = self.saved_id_dir
|
|
settings.INTERNET_DRAFT_ARCHIVE_DIR = self.saved_archive_dir
|
|
|
|
def write_draft_file(self, name, size):
|
|
f = open(os.path.join(self.id_dir, name), 'w')
|
|
f.write("a" * size)
|
|
f.close()
|
|
|
|
def test_in_draft_expire_freeze(self):
|
|
from ietf.doc.expire import in_draft_expire_freeze
|
|
|
|
Meeting.objects.create(number="123",
|
|
type=MeetingTypeName.objects.get(slug="ietf"),
|
|
date=datetime.date.today())
|
|
second_cut_off = Meeting.get_second_cut_off()
|
|
ietf_monday = Meeting.get_ietf_monday()
|
|
|
|
self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(second_cut_off - datetime.timedelta(days=7), datetime.time(0, 0, 0))))
|
|
self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(second_cut_off, datetime.time(0, 0, 0))))
|
|
self.assertTrue(in_draft_expire_freeze(datetime.datetime.combine(second_cut_off + datetime.timedelta(days=7), datetime.time(0, 0, 0))))
|
|
self.assertTrue(in_draft_expire_freeze(datetime.datetime.combine(ietf_monday - datetime.timedelta(days=1), datetime.time(0, 0, 0))))
|
|
self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(ietf_monday, datetime.time(0, 0, 0))))
|
|
|
|
def test_warn_expirable_drafts(self):
|
|
from ietf.doc.expire import get_soon_to_expire_drafts, send_expire_warning_for_draft
|
|
|
|
draft = make_test_data()
|
|
|
|
self.assertEqual(len(list(get_soon_to_expire_drafts(14))), 0)
|
|
|
|
# hack into expirable state
|
|
draft.unset_state("draft-iesg")
|
|
draft.expires = datetime.datetime.now() + datetime.timedelta(days=10)
|
|
draft.save_with_history([DocEvent.objects.create(doc=draft, type="changed_document", by=Person.objects.get(user__username="secretary"), desc="Test")])
|
|
|
|
self.assertEqual(len(list(get_soon_to_expire_drafts(14))), 1)
|
|
|
|
# test send warning
|
|
mailbox_before = len(outbox)
|
|
|
|
send_expire_warning_for_draft(draft)
|
|
|
|
self.assertEqual(len(outbox), mailbox_before + 1)
|
|
self.assertTrue('draft-ietf-mars-test@' in outbox[-1]['To']) # Gets the authors
|
|
self.assertTrue('mars-chairs@ietf.org' in outbox[-1]['Cc'])
|
|
self.assertTrue('aread@' in outbox[-1]['Cc'])
|
|
|
|
def test_expire_drafts(self):
|
|
from ietf.doc.expire import get_expired_drafts, send_expire_notice_for_draft, expire_draft
|
|
|
|
draft = make_test_data()
|
|
|
|
self.assertEqual(len(list(get_expired_drafts())), 0)
|
|
|
|
# hack into expirable state
|
|
draft.unset_state("draft-iesg")
|
|
draft.expires = datetime.datetime.now()
|
|
draft.save_with_history([DocEvent.objects.create(doc=draft, type="changed_document", by=Person.objects.get(user__username="secretary"), desc="Test")])
|
|
|
|
self.assertEqual(len(list(get_expired_drafts())), 1)
|
|
|
|
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="watching"))
|
|
|
|
self.assertEqual(len(list(get_expired_drafts())), 1)
|
|
|
|
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva"))
|
|
|
|
self.assertEqual(len(list(get_expired_drafts())), 0)
|
|
|
|
# test notice
|
|
mailbox_before = len(outbox)
|
|
|
|
send_expire_notice_for_draft(draft)
|
|
|
|
self.assertEqual(len(outbox), mailbox_before + 1)
|
|
self.assertTrue("expired" in outbox[-1]["Subject"])
|
|
self.assertTrue('draft-ietf-mars-test@' in outbox[-1]['To']) # gets authors
|
|
self.assertTrue('mars-chairs@ietf.org' in outbox[-1]['Cc'])
|
|
self.assertTrue('aread@' in outbox[-1]['Cc'])
|
|
|
|
# test expiry
|
|
txt = "%s-%s.txt" % (draft.name, draft.rev)
|
|
self.write_draft_file(txt, 5000)
|
|
|
|
expire_draft(draft)
|
|
|
|
draft = Document.objects.get(name=draft.name)
|
|
self.assertEqual(draft.get_state_slug(), "expired")
|
|
self.assertEqual(draft.get_state_slug("draft-iesg"), "dead")
|
|
self.assertTrue(draft.latest_event(type="expired_document"))
|
|
self.assertTrue(not os.path.exists(os.path.join(self.id_dir, txt)))
|
|
self.assertTrue(os.path.exists(os.path.join(self.archive_dir, txt)))
|
|
|
|
def test_clean_up_draft_files(self):
|
|
draft = make_test_data()
|
|
|
|
from ietf.doc.expire import clean_up_draft_files
|
|
|
|
# put unknown file
|
|
unknown = "draft-i-am-unknown-01.txt"
|
|
self.write_draft_file(unknown, 5000)
|
|
|
|
clean_up_draft_files()
|
|
|
|
self.assertTrue(not os.path.exists(os.path.join(self.id_dir, unknown)))
|
|
self.assertTrue(os.path.exists(os.path.join(self.archive_dir, "unknown_ids", unknown)))
|
|
|
|
|
|
# put file with malformed name (no revision)
|
|
malformed = draft.name + ".txt"
|
|
self.write_draft_file(malformed, 5000)
|
|
|
|
clean_up_draft_files()
|
|
|
|
self.assertTrue(not os.path.exists(os.path.join(self.id_dir, malformed)))
|
|
self.assertTrue(os.path.exists(os.path.join(self.archive_dir, "unknown_ids", malformed)))
|
|
|
|
|
|
# RFC draft
|
|
draft.set_state(State.objects.get(used=True, type="draft", slug="rfc"))
|
|
|
|
txt = "%s-%s.txt" % (draft.name, draft.rev)
|
|
self.write_draft_file(txt, 5000)
|
|
pdf = "%s-%s.pdf" % (draft.name, draft.rev)
|
|
self.write_draft_file(pdf, 5000)
|
|
|
|
clean_up_draft_files()
|
|
|
|
self.assertTrue(not os.path.exists(os.path.join(self.id_dir, txt)))
|
|
self.assertTrue(os.path.exists(os.path.join(self.archive_dir, txt)))
|
|
|
|
self.assertTrue(not os.path.exists(os.path.join(self.id_dir, pdf)))
|
|
self.assertTrue(os.path.exists(os.path.join(self.archive_dir, pdf)))
|
|
|
|
# expire draft
|
|
draft.set_state(State.objects.get(used=True, type="draft", slug="expired"))
|
|
draft.expires = datetime.datetime.now() - datetime.timedelta(days=1)
|
|
draft.save_with_history([DocEvent.objects.create(doc=draft, type="changed_document", by=Person.objects.get(user__username="secretary"), desc="Test")])
|
|
|
|
e = DocEvent()
|
|
e.doc = draft
|
|
e.by = Person.objects.get(name="(System)")
|
|
e.type = "expired_document"
|
|
e.text = "Document has expired"
|
|
e.time = draft.expires
|
|
e.save()
|
|
|
|
txt = "%s-%s.txt" % (draft.name, draft.rev)
|
|
self.write_draft_file(txt, 5000)
|
|
|
|
clean_up_draft_files()
|
|
|
|
self.assertTrue(not os.path.exists(os.path.join(self.id_dir, txt)))
|
|
self.assertTrue(os.path.exists(os.path.join(self.archive_dir, txt)))
|
|
|
|
|
|
class ExpireLastCallTests(TestCase):
|
|
def test_expire_last_call(self):
|
|
from ietf.doc.lastcall import get_expired_last_calls, expire_last_call
|
|
|
|
# check that non-expirable drafts aren't expired
|
|
|
|
draft = make_test_data()
|
|
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="lc"))
|
|
|
|
secretary = Person.objects.get(name="Sec Retary")
|
|
|
|
self.assertEqual(len(list(get_expired_last_calls())), 0)
|
|
|
|
e = LastCallDocEvent()
|
|
e.doc = draft
|
|
e.by = secretary
|
|
e.type = "sent_last_call"
|
|
e.text = "Last call sent"
|
|
e.expires = datetime.datetime.now() + datetime.timedelta(days=14)
|
|
e.save()
|
|
|
|
self.assertEqual(len(list(get_expired_last_calls())), 0)
|
|
|
|
# test expired
|
|
e = LastCallDocEvent()
|
|
e.doc = draft
|
|
e.by = secretary
|
|
e.type = "sent_last_call"
|
|
e.text = "Last call sent"
|
|
e.expires = datetime.datetime.now()
|
|
e.save()
|
|
|
|
drafts = list(get_expired_last_calls())
|
|
self.assertEqual(len(drafts), 1)
|
|
|
|
# expire it
|
|
mailbox_before = len(outbox)
|
|
events_before = draft.docevent_set.count()
|
|
|
|
expire_last_call(drafts[0])
|
|
|
|
draft = Document.objects.get(name=draft.name)
|
|
self.assertEqual(draft.get_state_slug("draft-iesg"), "writeupw")
|
|
self.assertEqual(draft.docevent_set.count(), events_before + 1)
|
|
self.assertEqual(len(outbox), mailbox_before + 1)
|
|
self.assertTrue("Last Call Expired" in outbox[-1]["Subject"])
|
|
self.assertTrue('iesg-secretary@' in outbox[-1]['Cc'])
|
|
self.assertTrue('aread@' in outbox[-1]['To'])
|
|
self.assertTrue('draft-ietf-mars-test@' in outbox[-1]['To'])
|
|
|
|
class IndividualInfoFormsTests(TestCase):
|
|
def test_doc_change_stream(self):
|
|
url = urlreverse('doc_change_stream', kwargs=dict(name=self.docname))
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
# get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code,200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('[type=submit]:contains("Save")')), 1)
|
|
|
|
# shift to ISE stream
|
|
empty_outbox()
|
|
r = self.client.post(url,dict(stream="ise",comment="7gRMTjBM"))
|
|
self.assertEqual(r.status_code,302)
|
|
self.doc = Document.objects.get(name=self.docname)
|
|
self.assertEqual(self.doc.stream_id,'ise')
|
|
self.assertEqual(len(outbox), 1)
|
|
self.assertTrue('Stream Change Notice' in outbox[0]['Subject'])
|
|
self.assertTrue('rfc-ise@' in outbox[0]['To'])
|
|
self.assertTrue('iesg@' in outbox[0]['To'])
|
|
self.assertTrue('7gRMTjBM' in str(outbox[0]))
|
|
self.assertTrue('7gRMTjBM' in self.doc.latest_event(DocEvent,type='added_comment').desc)
|
|
|
|
# shift to an unknown stream (it must be possible to throw a document out of any stream)
|
|
empty_outbox()
|
|
r = self.client.post(url,dict(stream=""))
|
|
self.assertEqual(r.status_code,302)
|
|
self.doc = Document.objects.get(name=self.docname)
|
|
self.assertEqual(self.doc.stream,None)
|
|
self.assertTrue('rfc-ise@' in outbox[0]['To'])
|
|
|
|
def test_doc_change_notify(self):
|
|
url = urlreverse('doc_change_notify', kwargs=dict(name=self.docname))
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
# get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code,200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('form input[name=notify]')),1)
|
|
|
|
# Provide a list
|
|
r = self.client.post(url,dict(notify="TJ2APh2P@ietf.org",save_addresses="1"))
|
|
self.assertEqual(r.status_code,302)
|
|
self.doc = Document.objects.get(name=self.docname)
|
|
self.assertEqual(self.doc.notify,'TJ2APh2P@ietf.org')
|
|
|
|
# Ask the form to regenerate the list
|
|
r = self.client.post(url,dict(regenerate_addresses="1"))
|
|
self.assertEqual(r.status_code,200)
|
|
self.doc = Document.objects.get(name=self.docname)
|
|
# Regenerate does not save!
|
|
self.assertEqual(self.doc.notify,'TJ2APh2P@ietf.org')
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(None,q('form input[name=notify]')[0].value)
|
|
|
|
def test_doc_change_intended_status(self):
|
|
url = urlreverse('doc_change_intended_status', kwargs=dict(name=self.docname))
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
# get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code,200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('[type=submit]:contains("Save")')), 1)
|
|
|
|
# don't allow status level to be cleared
|
|
r = self.client.post(url,dict(intended_std_level=""))
|
|
self.assertEqual(r.status_code,200)
|
|
q = PyQuery(r.content)
|
|
self.assertTrue(len(q('form .has-error')) > 0)
|
|
|
|
# change intended status level
|
|
messages_before = len(outbox)
|
|
r = self.client.post(url,dict(intended_std_level="bcp",comment="ZpyQFGmA"))
|
|
self.assertEqual(r.status_code,302)
|
|
self.doc = Document.objects.get(name=self.docname)
|
|
self.assertEqual(self.doc.intended_std_level_id,'bcp')
|
|
self.assertEqual(len(outbox),messages_before+1)
|
|
self.assertTrue('Intended Status ' in outbox[-1]['Subject'])
|
|
self.assertTrue('mars-chairs@' in outbox[-1]['To'])
|
|
self.assertTrue('ZpyQFGmA' in str(outbox[-1]))
|
|
|
|
self.assertTrue('ZpyQFGmA' in self.doc.latest_event(DocEvent,type='added_comment').desc)
|
|
|
|
def test_doc_change_telechat_date(self):
|
|
url = urlreverse('doc_change_telechat_date', kwargs=dict(name=self.docname))
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
# get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code,200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('[type=submit]:contains("Save")')), 1)
|
|
|
|
# set a date
|
|
empty_outbox()
|
|
self.assertFalse(self.doc.latest_event(TelechatDocEvent, "scheduled_for_telechat"))
|
|
telechat_date = TelechatDate.objects.active().order_by('date')[0].date
|
|
r = self.client.post(url,dict(telechat_date=telechat_date.isoformat()))
|
|
self.assertEqual(r.status_code,302)
|
|
self.doc = Document.objects.get(name=self.docname)
|
|
self.assertEqual(self.doc.latest_event(TelechatDocEvent, "scheduled_for_telechat").telechat_date,telechat_date)
|
|
self.assertEqual(len(outbox), 1)
|
|
self.assertTrue('Telechat update notice' in outbox[0]['Subject'])
|
|
self.assertTrue('iesg@' in outbox[0]['To'])
|
|
self.assertTrue('iesg-secretary@' in outbox[0]['To'])
|
|
|
|
# Take the doc back off any telechat
|
|
r = self.client.post(url,dict(telechat_date=""))
|
|
self.assertEqual(r.status_code, 302)
|
|
self.assertEqual(self.doc.latest_event(TelechatDocEvent, "scheduled_for_telechat").telechat_date,None)
|
|
|
|
def test_doc_change_iesg_note(self):
|
|
url = urlreverse('doc_change_iesg_note', kwargs=dict(name=self.docname))
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
# get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code,200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('[type=submit]:contains("Save")')),1)
|
|
|
|
# post
|
|
r = self.client.post(url,dict(note='ZpyQFGmA\r\nZpyQFGmA'))
|
|
self.assertEqual(r.status_code,302)
|
|
self.doc = Document.objects.get(name=self.docname)
|
|
self.assertEqual(self.doc.note,'ZpyQFGmA\nZpyQFGmA')
|
|
self.assertTrue('ZpyQFGmA' in self.doc.latest_event(DocEvent,type='added_comment').desc)
|
|
|
|
def test_doc_change_ad(self):
|
|
url = urlreverse('doc_change_ad', kwargs=dict(name=self.docname))
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
# get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code,200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('form select[name=ad]')),1)
|
|
|
|
# change ads
|
|
ad2 = Person.objects.get(name='Ad No2')
|
|
r = self.client.post(url,dict(ad=str(ad2.pk)))
|
|
self.assertEqual(r.status_code,302)
|
|
self.doc = Document.objects.get(name=self.docname)
|
|
self.assertEqual(self.doc.ad,ad2)
|
|
self.assertTrue(self.doc.latest_event(DocEvent,type="added_comment").desc.startswith('Shepherding AD changed'))
|
|
|
|
def test_doc_change_shepherd(self):
|
|
self.doc.shepherd = None
|
|
self.doc.save_with_history([DocEvent.objects.create(doc=self.doc, type="changed_shepherd", by=Person.objects.get(user__username="secretary"), desc="Test")])
|
|
|
|
url = urlreverse('doc_edit_shepherd',kwargs=dict(name=self.docname))
|
|
|
|
login_testing_unauthorized(self, "plain", url)
|
|
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code,403)
|
|
|
|
# get as the secretariat (and remain secretariat)
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code,200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('form input[id=id_shepherd]')),1)
|
|
|
|
# change the shepherd
|
|
plain_email = Email.objects.get(person__name="Plain Man")
|
|
r = self.client.post(url, dict(shepherd=plain_email.pk))
|
|
self.assertEqual(r.status_code,302)
|
|
self.doc = Document.objects.get(name=self.docname)
|
|
self.assertEqual(self.doc.shepherd, plain_email)
|
|
comment_events = self.doc.docevent_set.filter(time=self.doc.time,type="added_comment")
|
|
comments = '::'.join([x.desc for x in comment_events])
|
|
self.assertTrue('Document shepherd changed to Plain Man' in comments)
|
|
self.assertTrue('Notification list changed' in comments)
|
|
|
|
# save the form without changing the email (nothing should be saved)
|
|
r = self.client.post(url, dict(shepherd=plain_email.pk))
|
|
self.assertEqual(r.status_code, 302)
|
|
self.doc = Document.objects.get(name=self.docname)
|
|
self.assertEqual(set(comment_events), set(self.doc.docevent_set.filter(time=self.doc.time,type="added_comment")))
|
|
r = self.client.get(url)
|
|
self.assertTrue(any(['no changes have been made' in m.message for m in r.context['messages']]))
|
|
|
|
# Remove the shepherd
|
|
r = self.client.post(url, dict(shepherd=''))
|
|
self.assertEqual(r.status_code, 302)
|
|
self.doc = Document.objects.get(name=self.docname)
|
|
self.assertTrue(any(['Document shepherd changed to (None)' in x.desc for x in self.doc.docevent_set.filter(time=self.doc.time,type='added_comment')]))
|
|
|
|
# test buggy change
|
|
ad = Person.objects.get(name='Areað Irector')
|
|
two_answers = "%s,%s" % (plain_email, ad.email_set.all()[0])
|
|
r = self.client.post(url, dict(shepherd=two_answers))
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertTrue(len(q('form .has-error')) > 0)
|
|
|
|
def test_doc_change_shepherd_email(self):
|
|
self.doc.shepherd = None
|
|
self.doc.save_with_history([DocEvent.objects.create(doc=self.doc, type="changed_shepherd", by=Person.objects.get(user__username="secretary"), desc="Test")])
|
|
|
|
url = urlreverse('doc_change_shepherd_email',kwargs=dict(name=self.docname))
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 404)
|
|
|
|
self.doc.shepherd = Email.objects.get(person__user__username="ad1")
|
|
self.doc.save_with_history([DocEvent.objects.create(doc=self.doc, type="changed_shepherd", by=Person.objects.get(user__username="secretary"), desc="Test")])
|
|
|
|
login_testing_unauthorized(self, "plain", url)
|
|
|
|
self.doc.shepherd = Email.objects.get(person__user__username="plain")
|
|
self.doc.save_with_history([DocEvent.objects.create(doc=self.doc, type="changed_shepherd", by=Person.objects.get(user__username="secretary"), desc="Test")])
|
|
|
|
new_email = Email.objects.create(address="anotheremail@example.com", person=self.doc.shepherd.person)
|
|
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
|
|
# change the shepherd email
|
|
r = self.client.post(url, dict(shepherd=new_email))
|
|
self.assertEqual(r.status_code, 302)
|
|
self.doc = Document.objects.get(name=self.docname)
|
|
self.assertEqual(self.doc.shepherd, new_email)
|
|
comment_event = self.doc.latest_event(DocEvent, type="added_comment")
|
|
self.assertTrue(comment_event.desc.startswith('Document shepherd email changed'))
|
|
|
|
# save the form without changing the email (nothing should be saved)
|
|
r = self.client.post(url, dict(shepherd=new_email))
|
|
self.assertEqual(r.status_code, 302)
|
|
self.assertEqual(comment_event, self.doc.latest_event(DocEvent, type="added_comment"))
|
|
|
|
|
|
def test_doc_view_shepherd_writeup(self):
|
|
url = urlreverse('doc_shepherd_writeup',kwargs=dict(name=self.docname))
|
|
|
|
# get as a shepherd
|
|
self.client.login(username="plain", password="plain+password")
|
|
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code,200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('#content a:contains("Edit")')), 1)
|
|
|
|
# Try again when no longer a shepherd.
|
|
|
|
self.doc.shepherd = None
|
|
self.doc.save_with_history([DocEvent.objects.create(doc=self.doc, type="changed_shepherd", by=Person.objects.get(user__username="secretary"), desc="Test")])
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code,200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('#content a:contains("Edit")')), 0)
|
|
|
|
def test_doc_change_shepherd_writeup(self):
|
|
url = urlreverse('doc_edit_shepherd_writeup',kwargs=dict(name=self.docname))
|
|
|
|
# get
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code,200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('form textarea[id=id_content]')),1)
|
|
|
|
# direct edit
|
|
r = self.client.post(url,dict(content='here is a new writeup',submit_response="1"))
|
|
self.assertEqual(r.status_code,302)
|
|
self.doc = Document.objects.get(name=self.docname)
|
|
self.assertTrue(self.doc.latest_event(WriteupDocEvent,type="changed_protocol_writeup").text.startswith('here is a new writeup'))
|
|
|
|
# file upload
|
|
test_file = StringIO.StringIO("This is a different writeup.")
|
|
test_file.name = "unnamed"
|
|
r = self.client.post(url,dict(txt=test_file,submit_response="1"))
|
|
self.assertEqual(r.status_code, 302)
|
|
self.assertTrue(self.doc.latest_event(WriteupDocEvent,type="changed_protocol_writeup").text.startswith('This is a different writeup.'))
|
|
|
|
# template reset
|
|
r = self.client.post(url,dict(txt=test_file,reset_text="1"))
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertTrue(q('textarea')[0].text.strip().startswith("As required by RFC 4858"))
|
|
|
|
def setUp(self):
|
|
make_test_data()
|
|
self.docname='draft-ietf-mars-test'
|
|
self.doc = Document.objects.get(name=self.docname)
|
|
|
|
|
|
class SubmitToIesgTests(TestCase):
|
|
def test_verify_permissions(self):
|
|
|
|
def verify_fail(username):
|
|
if username:
|
|
self.client.login(username=username, password=username+"+password")
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code,404)
|
|
|
|
def verify_can_see(username):
|
|
self.client.login(username=username, password=username+"+password")
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code,200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('form input[name="confirm"]')),1)
|
|
|
|
url = urlreverse('doc_to_iesg', kwargs=dict(name=self.docname))
|
|
|
|
for username in [None,'plain','iana','iab chair']:
|
|
verify_fail(username)
|
|
|
|
for username in ['marschairman','secretary','ad']:
|
|
verify_can_see(username)
|
|
|
|
def test_cancel_submission(self):
|
|
url = urlreverse('doc_to_iesg', kwargs=dict(name=self.docname))
|
|
self.client.login(username="marschairman", password="marschairman+password")
|
|
|
|
r = self.client.post(url, dict(cancel="1"))
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
doc = Document.objects.get(pk=self.doc.pk)
|
|
self.assertTrue(doc.get_state('draft-iesg')==None)
|
|
|
|
def test_confirm_submission(self):
|
|
url = urlreverse('doc_to_iesg', kwargs=dict(name=self.docname))
|
|
self.client.login(username="marschairman", password="marschairman+password")
|
|
|
|
docevent_count_pre = self.doc.docevent_set.count()
|
|
mailbox_before = len(outbox)
|
|
|
|
r = self.client.post(url, dict(confirm="1"))
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
doc = Document.objects.get(pk=self.doc.pk)
|
|
self.assertTrue(doc.get_state('draft-iesg').slug=='pub-req')
|
|
self.assertTrue(doc.get_state('draft-stream-ietf').slug=='sub-pub')
|
|
self.assertTrue(doc.ad!=None)
|
|
self.assertTrue(doc.docevent_set.count() != docevent_count_pre)
|
|
self.assertEqual(len(outbox), mailbox_before + 1)
|
|
self.assertTrue("Publication has been requested" in outbox[-1]['Subject'])
|
|
self.assertTrue("aread@" in outbox[-1]['To'])
|
|
self.assertTrue("iesg-secretary@" in outbox[-1]['Cc'])
|
|
|
|
def setUp(self):
|
|
make_test_data()
|
|
self.docname='draft-ietf-mars-test'
|
|
self.doc = Document.objects.get(name=self.docname)
|
|
self.doc.unset_state('draft-iesg')
|
|
|
|
|
|
class RequestPublicationTests(TestCase):
|
|
def test_request_publication(self):
|
|
draft = make_test_data()
|
|
draft.stream = StreamName.objects.get(slug="iab")
|
|
draft.group = Group.objects.get(acronym="iab")
|
|
draft.intended_std_level = IntendedStdLevelName.objects.get(slug="inf")
|
|
draft.save_with_history([DocEvent.objects.create(doc=draft, type="changed_document", by=Person.objects.get(user__username="secretary"), desc="Test")])
|
|
draft.set_state(State.objects.get(used=True, type="draft-stream-iab", slug="approved"))
|
|
|
|
url = urlreverse('doc_request_publication', kwargs=dict(name=draft.name))
|
|
login_testing_unauthorized(self, "iab-chair", url)
|
|
|
|
# normal get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
subject = q('input#id_subject')[0].get("value")
|
|
self.assertTrue("Document Action" in subject)
|
|
body = q('#id_body').text()
|
|
self.assertTrue("Informational" in body)
|
|
self.assertTrue("IAB" in body)
|
|
|
|
# approve
|
|
mailbox_before = len(outbox)
|
|
|
|
r = self.client.post(url, dict(subject=subject, body=body, skiprfceditorpost="1"))
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(name=draft.name)
|
|
self.assertEqual(draft.get_state_slug("draft-stream-iab"), "rfc-edit")
|
|
|
|
self.assertEqual(len(outbox), mailbox_before + 2)
|
|
|
|
self.assertTrue("Document Action" in outbox[-2]['Subject'])
|
|
self.assertTrue("rfc-editor@" in outbox[-2]['To'])
|
|
|
|
self.assertTrue("Document Action" in outbox[-1]['Subject'])
|
|
self.assertTrue("drafts-approval@icann.org" in outbox[-1]['To'])
|
|
|
|
self.assertTrue("Document Action" in draft.message_set.order_by("-time")[0].subject)
|
|
|
|
class AdoptDraftTests(TestCase):
|
|
def test_adopt_document(self):
|
|
draft = make_test_data()
|
|
draft.stream = None
|
|
draft.group = Group.objects.get(type="individ")
|
|
draft.unset_state("draft-stream-ietf")
|
|
draft.save_with_history([DocEvent.objects.create(doc=draft, type="changed_document", by=Person.objects.get(user__username="secretary"), desc="Test")])
|
|
|
|
url = urlreverse('doc_adopt_draft', kwargs=dict(name=draft.name))
|
|
login_testing_unauthorized(self, "marschairman", url)
|
|
|
|
# get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('form select[name="group"] option')), 1) # we can only select "mars"
|
|
|
|
# adopt in mars WG
|
|
mailbox_before = len(outbox)
|
|
events_before = draft.docevent_set.count()
|
|
mars = Group.objects.get(acronym="mars")
|
|
call_issued = State.objects.get(type='draft-stream-ietf',slug='c-adopt')
|
|
r = self.client.post(url,
|
|
dict(comment="some comment",
|
|
group=mars.pk,
|
|
newstate=call_issued.pk,
|
|
weeks="10"))
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(pk=draft.pk)
|
|
self.assertEqual(draft.group.acronym, "mars")
|
|
self.assertEqual(draft.stream_id, "ietf")
|
|
self.assertEqual(draft.docevent_set.count() - events_before, 5)
|
|
self.assertEqual(draft.notify,"aliens@example.mars")
|
|
self.assertEqual(len(outbox), mailbox_before + 1)
|
|
self.assertTrue("Call For Adoption" in outbox[-1]["Subject"])
|
|
self.assertTrue("mars-chairs@ietf.org" in outbox[-1]['To'])
|
|
self.assertTrue("draft-ietf-mars-test@" in outbox[-1]['To'])
|
|
self.assertTrue("mars-wg@" in outbox[-1]['To'])
|
|
|
|
self.assertFalse(mars.list_email in draft.notify)
|
|
|
|
class ChangeStreamStateTests(TestCase):
|
|
def test_set_tags(self):
|
|
draft = make_test_data()
|
|
draft.tags = DocTagName.objects.filter(slug="w-expert")
|
|
draft.group.unused_tags.add("w-refdoc")
|
|
|
|
url = urlreverse('doc_change_stream_state', kwargs=dict(name=draft.name, state_type="draft-stream-ietf"))
|
|
login_testing_unauthorized(self, "marschairman", url)
|
|
|
|
# get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
# make sure the unused tags are hidden
|
|
unused = draft.group.unused_tags.values_list("slug", flat=True)
|
|
for t in q("input[name=tags]"):
|
|
self.assertTrue(t.attrib["value"] not in unused)
|
|
|
|
# set tags
|
|
mailbox_before = len(outbox)
|
|
events_before = draft.docevent_set.count()
|
|
r = self.client.post(url,
|
|
dict(new_state=draft.get_state("draft-stream-%s" % draft.stream_id).pk,
|
|
comment="some comment",
|
|
weeks="10",
|
|
tags=["need-aut", "sheph-u"],
|
|
))
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(pk=draft.pk)
|
|
self.assertEqual(draft.tags.count(), 2)
|
|
self.assertEqual(draft.tags.filter(slug="w-expert").count(), 0)
|
|
self.assertEqual(draft.tags.filter(slug="need-aut").count(), 1)
|
|
self.assertEqual(draft.tags.filter(slug="sheph-u").count(), 1)
|
|
self.assertEqual(draft.docevent_set.count() - events_before, 2)
|
|
self.assertEqual(len(outbox), mailbox_before + 1)
|
|
self.assertTrue("tags changed" in outbox[-1]["Subject"].lower())
|
|
self.assertTrue("mars-chairs@ietf.org" in unicode(outbox[-1]))
|
|
self.assertTrue("marsdelegate@ietf.org" in unicode(outbox[-1]))
|
|
self.assertTrue("plain@example.com" in unicode(outbox[-1]))
|
|
|
|
def test_set_initial_state(self):
|
|
draft = make_test_data()
|
|
draft.unset_state("draft-stream-%s"%draft.stream_id)
|
|
|
|
url = urlreverse('doc_change_stream_state', kwargs=dict(name=draft.name, state_type="draft-stream-ietf"))
|
|
login_testing_unauthorized(self, "marschairman", url)
|
|
|
|
# set a state when no state exists
|
|
old_state = draft.get_state("draft-stream-%s" % draft.stream_id )
|
|
self.assertEqual(old_state,None)
|
|
new_state = State.objects.get(used=True, type="draft-stream-%s" % draft.stream_id, slug="parked")
|
|
empty_outbox()
|
|
events_before = draft.docevent_set.count()
|
|
|
|
r = self.client.post(url,
|
|
dict(new_state=new_state.pk,
|
|
comment="some comment",
|
|
weeks="10",
|
|
tags=[t.pk for t in draft.tags.filter(slug__in=get_tags_for_stream_id(draft.stream_id))],
|
|
))
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(pk=draft.pk)
|
|
self.assertEqual(draft.get_state("draft-stream-%s" % draft.stream_id), new_state)
|
|
self.assertEqual(draft.docevent_set.count() - events_before, 2)
|
|
reminder = DocReminder.objects.filter(event__doc=draft, type="stream-s")
|
|
self.assertEqual(len(reminder), 1)
|
|
due = datetime.datetime.now() + datetime.timedelta(weeks=10)
|
|
self.assertTrue(due - datetime.timedelta(days=1) <= reminder[0].due <= due + datetime.timedelta(days=1))
|
|
self.assertEqual(len(outbox), 1)
|
|
self.assertTrue("state changed" in outbox[0]["Subject"].lower())
|
|
self.assertTrue("mars-chairs@ietf.org" in unicode(outbox[0]))
|
|
self.assertTrue("marsdelegate@ietf.org" in unicode(outbox[0]))
|
|
|
|
def test_set_state(self):
|
|
draft = make_test_data()
|
|
|
|
url = urlreverse('doc_change_stream_state', kwargs=dict(name=draft.name, state_type="draft-stream-ietf"))
|
|
login_testing_unauthorized(self, "marschairman", url)
|
|
|
|
# get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
# make sure the unused states are hidden
|
|
unused = draft.group.unused_states.values_list("pk", flat=True)
|
|
for t in q("select[name=new_state]").find("option[name=tags]"):
|
|
self.assertTrue(t.attrib["value"] not in unused)
|
|
self.assertEqual(len(q('select[name=new_state]')), 1)
|
|
|
|
# set new state
|
|
old_state = draft.get_state("draft-stream-%s" % draft.stream_id )
|
|
new_state = State.objects.get(used=True, type="draft-stream-%s" % draft.stream_id, slug="parked")
|
|
self.assertNotEqual(old_state, new_state)
|
|
empty_outbox()
|
|
events_before = draft.docevent_set.count()
|
|
|
|
r = self.client.post(url,
|
|
dict(new_state=new_state.pk,
|
|
comment="some comment",
|
|
weeks="10",
|
|
tags=[t.pk for t in draft.tags.filter(slug__in=get_tags_for_stream_id(draft.stream_id))],
|
|
))
|
|
self.assertEqual(r.status_code, 302)
|
|
|
|
draft = Document.objects.get(pk=draft.pk)
|
|
self.assertEqual(draft.get_state("draft-stream-%s" % draft.stream_id), new_state)
|
|
self.assertEqual(draft.docevent_set.count() - events_before, 2)
|
|
reminder = DocReminder.objects.filter(event__doc=draft, type="stream-s")
|
|
self.assertEqual(len(reminder), 1)
|
|
due = datetime.datetime.now() + datetime.timedelta(weeks=10)
|
|
self.assertTrue(due - datetime.timedelta(days=1) <= reminder[0].due <= due + datetime.timedelta(days=1))
|
|
self.assertEqual(len(outbox), 1)
|
|
self.assertTrue("state changed" in outbox[0]["Subject"].lower())
|
|
self.assertTrue("mars-chairs@ietf.org" in unicode(outbox[0]))
|
|
self.assertTrue("marsdelegate@ietf.org" in unicode(outbox[0]))
|
|
|
|
def test_pubreq_validation(self):
|
|
draft = make_test_data()
|
|
|
|
url = urlreverse('doc_change_stream_state', kwargs=dict(name=draft.name, state_type="draft-stream-ietf"))
|
|
login_testing_unauthorized(self, "marschairman", url)
|
|
|
|
old_state = draft.get_state("draft-stream-%s" % draft.stream_id )
|
|
new_state = State.objects.get(used=True, type="draft-stream-%s" % draft.stream_id, slug="sub-pub")
|
|
self.assertNotEqual(old_state, new_state)
|
|
|
|
r = self.client.post(url,
|
|
dict(new_state=new_state.pk,
|
|
comment="some comment",
|
|
weeks="10",
|
|
tags=[t.pk for t in draft.tags.filter(slug__in=get_tags_for_stream_id(draft.stream_id))],
|
|
))
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertTrue(len(q('form .has-error')) > 0)
|
|
|
|
class ChangeReplacesTests(TestCase):
|
|
def setUp(self):
|
|
|
|
make_test_data()
|
|
|
|
mars_wg = Group.objects.get(acronym='mars')
|
|
|
|
self.basea = Document.objects.create(
|
|
name="draft-test-base-a",
|
|
time=datetime.datetime.now(),
|
|
type_id="draft",
|
|
title="Base A",
|
|
stream_id="ietf",
|
|
expires=datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE),
|
|
group=mars_wg,
|
|
)
|
|
p = Person.objects.create(address="basea_author")
|
|
e = Email.objects.create(address="basea_author@example.com", person=p)
|
|
self.basea.documentauthor_set.create(person=p, email=e, order=1)
|
|
|
|
self.baseb = Document.objects.create(
|
|
name="draft-test-base-b",
|
|
time=datetime.datetime.now()-datetime.timedelta(days=365),
|
|
type_id="draft",
|
|
title="Base B",
|
|
stream_id="ietf",
|
|
expires=datetime.datetime.now() - datetime.timedelta(days = 365 - settings.INTERNET_DRAFT_DAYS_TO_EXPIRE),
|
|
group=mars_wg,
|
|
)
|
|
p = Person.objects.create(name="baseb_author")
|
|
e = Email.objects.create(address="baseb_author@example.com", person=p)
|
|
self.baseb.documentauthor_set.create(person=p, email=e, order=1)
|
|
|
|
self.replacea = Document.objects.create(
|
|
name="draft-test-replace-a",
|
|
time=datetime.datetime.now(),
|
|
type_id="draft",
|
|
title="Replace Base A",
|
|
stream_id="ietf",
|
|
expires=datetime.datetime.now() + datetime.timedelta(days = settings.INTERNET_DRAFT_DAYS_TO_EXPIRE),
|
|
group=mars_wg,
|
|
)
|
|
p = Person.objects.create(name="replacea_author")
|
|
e = Email.objects.create(address="replacea_author@example.com", person=p)
|
|
self.replacea.documentauthor_set.create(person=p, email=e, order=1)
|
|
|
|
self.replaceboth = Document.objects.create(
|
|
name="draft-test-replace-both",
|
|
time=datetime.datetime.now(),
|
|
type_id="draft",
|
|
title="Replace Base A and Base B",
|
|
stream_id="ietf",
|
|
expires=datetime.datetime.now() + datetime.timedelta(days = settings.INTERNET_DRAFT_DAYS_TO_EXPIRE),
|
|
group=mars_wg,
|
|
)
|
|
p = Person.objects.create(name="replaceboth_author")
|
|
e = Email.objects.create(address="replaceboth_author@example.com", person=p)
|
|
self.replaceboth.documentauthor_set.create(person=p, email=e, order=1)
|
|
|
|
self.basea.set_state(State.objects.get(used=True, type="draft", slug="active"))
|
|
self.baseb.set_state(State.objects.get(used=True, type="draft", slug="expired"))
|
|
self.replacea.set_state(State.objects.get(used=True, type="draft", slug="active"))
|
|
self.replaceboth.set_state(State.objects.get(used=True, type="draft", slug="active"))
|
|
|
|
DocAlias.objects.create(document=self.basea,name=self.basea.name)
|
|
DocAlias.objects.create(document=self.baseb,name=self.baseb.name)
|
|
DocAlias.objects.create(document=self.replacea,name=self.replacea.name)
|
|
DocAlias.objects.create(document=self.replaceboth,name=self.replaceboth.name)
|
|
|
|
def test_change_replaces(self):
|
|
|
|
url = urlreverse('doc_change_replaces', kwargs=dict(name=self.replacea.name))
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
# normal get
|
|
r = self.client.get(url)
|
|
self.assertEqual(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEqual(len(q('[type=submit]:contains("Save")')), 1)
|
|
|
|
# Post that says replacea replaces base a
|
|
empty_outbox()
|
|
RelatedDocument.objects.create(source=self.replacea, target=self.basea.docalias_set.first(),
|
|
relationship=DocRelationshipName.objects.get(slug="possibly-replaces"))
|
|
self.assertEqual(self.basea.get_state().slug,'active')
|
|
r = self.client.post(url, dict(replaces=self.basea.name))
|
|
self.assertEqual(r.status_code, 302)
|
|
self.assertEqual(RelatedDocument.objects.filter(relationship__slug='replaces',source=self.replacea).count(),1)
|
|
self.assertEqual(Document.objects.get(name='draft-test-base-a').get_state().slug,'repl')
|
|
self.assertTrue(not RelatedDocument.objects.filter(relationship='possibly-replaces', source=self.replacea))
|
|
self.assertEqual(len(outbox), 1)
|
|
self.assertTrue('replacement status updated' in outbox[-1]['Subject'])
|
|
self.assertTrue('replacea_author@' in outbox[-1]['To'])
|
|
self.assertTrue('basea_author@' in outbox[-1]['To'])
|
|
|
|
empty_outbox()
|
|
# Post that says replaceboth replaces both base a and base b
|
|
url = urlreverse('doc_change_replaces', kwargs=dict(name=self.replaceboth.name))
|
|
self.assertEqual(self.baseb.get_state().slug,'expired')
|
|
r = self.client.post(url, dict(replaces=self.basea.name + "," + self.baseb.name))
|
|
self.assertEqual(r.status_code, 302)
|
|
self.assertEqual(Document.objects.get(name='draft-test-base-a').get_state().slug,'repl')
|
|
self.assertEqual(Document.objects.get(name='draft-test-base-b').get_state().slug,'repl')
|
|
self.assertEqual(len(outbox), 1)
|
|
self.assertTrue('basea_author@' in outbox[-1]['To'])
|
|
self.assertTrue('baseb_author@' in outbox[-1]['To'])
|
|
self.assertTrue('replaceboth_author@' in outbox[-1]['To'])
|
|
|
|
# Post that undoes replaceboth
|
|
empty_outbox()
|
|
r = self.client.post(url, dict(replaces=""))
|
|
self.assertEqual(r.status_code, 302)
|
|
self.assertEqual(Document.objects.get(name='draft-test-base-a').get_state().slug,'repl') # Because A is still also replaced by replacea
|
|
self.assertEqual(Document.objects.get(name='draft-test-base-b').get_state().slug,'expired')
|
|
self.assertEqual(len(outbox), 1)
|
|
self.assertTrue('basea_author@' in outbox[-1]['To'])
|
|
self.assertTrue('baseb_author@' in outbox[-1]['To'])
|
|
self.assertTrue('replaceboth_author@' in outbox[-1]['To'])
|
|
|
|
# Post that undoes replacea
|
|
empty_outbox()
|
|
url = urlreverse('doc_change_replaces', kwargs=dict(name=self.replacea.name))
|
|
r = self.client.post(url, dict(replaces=""))
|
|
self.assertEqual(r.status_code, 302)
|
|
self.assertEqual(Document.objects.get(name='draft-test-base-a').get_state().slug,'active')
|
|
self.assertTrue('basea_author@' in outbox[-1]['To'])
|
|
self.assertTrue('replacea_author@' in outbox[-1]['To'])
|
|
|
|
|
|
def test_review_possibly_replaces(self):
|
|
replaced = self.basea.docalias_set.first()
|
|
RelatedDocument.objects.create(source=self.replacea, target=replaced,
|
|
relationship=DocRelationshipName.objects.get(slug="possibly-replaces"))
|
|
|
|
url = urlreverse('doc_review_possibly_replaces', kwargs=dict(name=self.replacea.name))
|
|
login_testing_unauthorized(self, "secretary", url)
|
|
|
|
r = self.client.get(url)
|
|
self.assertEquals(r.status_code, 200)
|
|
q = PyQuery(r.content)
|
|
self.assertEquals(len(q('form[name=review-suggested-replaces]')), 1)
|
|
|
|
r = self.client.post(url, dict(replaces=[replaced.pk]))
|
|
self.assertEquals(r.status_code, 302)
|
|
self.assertTrue(not self.replacea.related_that_doc("possibly-replaces"))
|
|
self.assertEqual(len(self.replacea.related_that_doc("replaces")), 1)
|
|
self.assertEquals(Document.objects.get(pk=self.basea.pk).get_state().slug, 'repl')
|