Merged [7076] from rjsparks@nostrum.com:
Sets the State(type=draft) to Replaced when a document is replaced using views_draft.replaces.
Sets the state back to Active or Expired when a document is no longer replaced by another document.
Adds tests for the above functionality.
Provides a patch to repair the state of documents pointed to by RelatedDocument(relationship__slug='replaces') objects created by views_draft.replaces before this fix.
Fixes bug 1234
- Legacy-Id: 7222
Note: SVN reference [7076] has been migrated to Git commit a3da5bbd87
This commit is contained in:
commit
3abaab1d98
|
@ -1098,3 +1098,102 @@ class ChangeStreamStateTests(TestCase):
|
|||
self.assertTrue("marschairman@ietf.org" in unicode(outbox[-1]))
|
||||
self.assertTrue("marsdelegate@ietf.org" in unicode(outbox[-1]))
|
||||
|
||||
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,
|
||||
)
|
||||
|
||||
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,
|
||||
)
|
||||
|
||||
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,
|
||||
)
|
||||
|
||||
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,
|
||||
)
|
||||
|
||||
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.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('form[class=change-replaces]')), 1)
|
||||
|
||||
# Post that says replacea replaces base a
|
||||
self.assertEquals(self.basea.get_state().slug,'active')
|
||||
repljson='{"%d":"%s"}'%(DocAlias.objects.get(name=self.basea.name).id,self.basea.name)
|
||||
r = self.client.post(url, dict(replaces=repljson))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
self.assertEqual(RelatedDocument.objects.filter(relationship__slug='replaces',source=self.replacea).count(),1)
|
||||
self.assertEquals(Document.objects.get(name='draft-test-base-a').get_state().slug,'repl')
|
||||
|
||||
# Post that says replaceboth replaces both base a and base b
|
||||
url = urlreverse('doc_change_replaces', kwargs=dict(name=self.replaceboth.name))
|
||||
self.assertEquals(self.baseb.get_state().slug,'expired')
|
||||
repljson='{"%d":"%s","%d":"%s"}'%(DocAlias.objects.get(name=self.basea.name).id,self.basea.name,
|
||||
DocAlias.objects.get(name=self.baseb.name).id,self.baseb.name)
|
||||
r = self.client.post(url, dict(replaces=repljson))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
self.assertEquals(Document.objects.get(name='draft-test-base-a').get_state().slug,'repl')
|
||||
self.assertEquals(Document.objects.get(name='draft-test-base-b').get_state().slug,'repl')
|
||||
|
||||
# Post that undoes replaceboth
|
||||
repljson='{}'
|
||||
r = self.client.post(url, dict(replaces=repljson))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
self.assertEquals(Document.objects.get(name='draft-test-base-a').get_state().slug,'repl') # Because A is still also replaced by replacea
|
||||
self.assertEquals(Document.objects.get(name='draft-test-base-b').get_state().slug,'expired')
|
||||
|
||||
# Post that undoes replacea
|
||||
url = urlreverse('doc_change_replaces', kwargs=dict(name=self.replacea.name))
|
||||
r = self.client.post(url, dict(replaces=repljson))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
self.assertEquals(Document.objects.get(name='draft-test-base-a').get_state().slug,'active')
|
||||
|
||||
|
|
|
@ -354,13 +354,14 @@ def replaces(request, name):
|
|||
for d in old_replaces:
|
||||
if d not in new_replaces:
|
||||
emails = collect_email_addresses(emails, d.document)
|
||||
RelatedDocument.objects.filter(source=doc, target=d,
|
||||
relationship=relationship).delete()
|
||||
RelatedDocument.objects.filter(source=doc, target=d, relationship=relationship).delete()
|
||||
if not RelatedDocument.objects.filter(target=d, relationship=relationship):
|
||||
d.document.set_state(State.objects.get(type='draft',slug='active' if d.document.expires>datetime.datetime.now() else 'expired'))
|
||||
for d in new_replaces:
|
||||
if d not in old_replaces:
|
||||
emails = collect_email_addresses(emails, d.document)
|
||||
RelatedDocument.objects.create(source=doc, target=d,
|
||||
relationship=relationship)
|
||||
RelatedDocument.objects.create(source=doc, target=d, relationship=relationship)
|
||||
d.document.set_state(State.objects.get(type='draft',slug='repl'))
|
||||
e = DocEvent(doc=doc,by=login,type='changed_document')
|
||||
new_replaces_names = ", ".join([d.name for d in new_replaces])
|
||||
if not new_replaces_names:
|
||||
|
|
28
ietf/patches/fix_replaced_states.py
Normal file
28
ietf/patches/fix_replaced_states.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/env python
|
||||
from ietf import settings
|
||||
from django.core import management
|
||||
management.setup_environ(settings)
|
||||
|
||||
from ietf.doc.models import RelatedDocument,State,DocEvent
|
||||
from ietf.person.models import Person
|
||||
|
||||
|
||||
relevant_relations = RelatedDocument.objects.filter(relationship__slug='replaces',
|
||||
target__document__type__slug='draft',
|
||||
target__document__states__type='draft',
|
||||
target__document__states__slug__in=['active','expired'])
|
||||
|
||||
affected_docs = set([x.target.document for x in relevant_relations])
|
||||
|
||||
replaced_state = State.objects.get(type='draft',slug='repl')
|
||||
|
||||
system_user = Person.objects.get(name="(System)")
|
||||
|
||||
for d in affected_docs:
|
||||
d.set_state(replaced_state)
|
||||
DocEvent.objects.create(type="added_comment",
|
||||
doc=d,
|
||||
by=system_user,
|
||||
desc='Draft state administratively corrected to Replaced',
|
||||
)
|
||||
|
Loading…
Reference in a new issue