Fix issue where draft resurrect feature does not move most recent draft file from the archive directory back to the current draft directory. Fixes #2646. Commit ready for merge
- Legacy-Id: 17027
This commit is contained in:
parent
34f93932a2
commit
9882d7fda8
ietf/doc
|
@ -16,6 +16,7 @@ from django.conf import settings
|
|||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
from ietf.doc.expire import get_expired_drafts, send_expire_notice_for_draft, expire_draft
|
||||
from ietf.doc.factories import IndividualDraftFactory, WgDraftFactory, RgDraftFactory, DocEventFactory
|
||||
from ietf.doc.models import ( Document, DocReminder, DocEvent,
|
||||
ConsensusDocEvent, LastCallDocEvent, RelatedDocument, State, TelechatDocEvent,
|
||||
|
@ -492,7 +493,33 @@ class EditInfoTests(TestCase):
|
|||
self.assertEqual(draft.latest_event(ConsensusDocEvent, type="changed_consensus").consensus, None)
|
||||
|
||||
|
||||
class ResurrectTests(TestCase):
|
||||
class DraftFileMixin():
|
||||
'''A mixin to setup temporary draft directories and files'''
|
||||
def setUp(self):
|
||||
self.saved_id_dir = settings.INTERNET_DRAFT_PATH
|
||||
self.saved_archive_dir = settings.INTERNET_DRAFT_ARCHIVE_DIR
|
||||
self.id_dir = self.tempdir('id')
|
||||
self.archive_dir = self.tempdir('id-archive')
|
||||
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 = io.open(os.path.join(self.id_dir, name), 'w')
|
||||
f.write("a" * size)
|
||||
f.close()
|
||||
|
||||
|
||||
class ResurrectTests(DraftFileMixin, TestCase):
|
||||
def test_request_resurrect(self):
|
||||
draft = WgDraftFactory(states=[('draft','expired')])
|
||||
|
||||
|
@ -526,14 +553,17 @@ class ResurrectTests(TestCase):
|
|||
|
||||
def test_resurrect(self):
|
||||
ad = Person.objects.get(name="Areað Irector")
|
||||
draft = WgDraftFactory(ad=ad,states=[('draft','expired')])
|
||||
draft = WgDraftFactory(ad=ad,states=[('draft','active')])
|
||||
DocEventFactory(doc=draft,type="requested_resurrect",by=ad)
|
||||
|
||||
url = urlreverse('ietf.doc.views_draft.resurrect', kwargs=dict(name=draft.name))
|
||||
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
# create file and expire draft
|
||||
txt = "%s-%s.txt" % (draft.name, draft.rev)
|
||||
self.write_draft_file(txt, 5000)
|
||||
expire_draft(draft)
|
||||
|
||||
# normal get
|
||||
url = urlreverse('ietf.doc.views_draft.resurrect', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
|
@ -556,31 +586,12 @@ class ResurrectTests(TestCase):
|
|||
self.assertTrue('iesg-secretary' in outbox[-1]['To'])
|
||||
self.assertTrue('aread' in outbox[-1]['To'])
|
||||
|
||||
# ensure file restored from archive directory
|
||||
self.assertTrue(os.path.exists(os.path.join(self.id_dir, txt)))
|
||||
self.assertTrue(not os.path.exists(os.path.join(self.archive_dir, txt)))
|
||||
|
||||
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 = self.tempdir('id')
|
||||
self.archive_dir = self.tempdir('id-archive')
|
||||
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 = io.open(os.path.join(self.id_dir, name), 'w')
|
||||
f.write("a" * size)
|
||||
f.close()
|
||||
|
||||
class ExpireIDsTests(DraftFileMixin, TestCase):
|
||||
def test_in_draft_expire_freeze(self):
|
||||
from ietf.doc.expire import in_draft_expire_freeze
|
||||
|
||||
|
@ -623,8 +634,6 @@ class ExpireIDsTests(TestCase):
|
|||
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
|
||||
|
||||
mars = GroupFactory(type_id='wg',acronym='mars')
|
||||
ad_role = RoleFactory(group=mars, name_id='ad', person=Person.objects.get(user__username='ad'))
|
||||
draft = WgDraftFactory(name='draft-ietf-mars-test',group=mars)
|
||||
|
|
|
@ -7,6 +7,9 @@ from __future__ import absolute_import, print_function, unicode_literals
|
|||
# changing state and metadata on Internet Drafts
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import glob
|
||||
import shutil
|
||||
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
|
@ -47,6 +50,7 @@ from ietf.person.fields import SearchableEmailField
|
|||
from ietf.person.models import Person, Email
|
||||
from ietf.utils.mail import send_mail, send_mail_message, on_behalf_of
|
||||
from ietf.utils.textupload import get_cleaned_text_file_content
|
||||
from ietf.utils import log
|
||||
from ietf.mailtrigger.utils import gather_address_lists
|
||||
|
||||
class ChangeStateForm(forms.Form):
|
||||
|
@ -835,6 +839,8 @@ def resurrect(request, name):
|
|||
doc.expires = datetime.datetime.now() + datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE)
|
||||
doc.save_with_history(events)
|
||||
|
||||
restore_draft_file(request, doc)
|
||||
|
||||
return HttpResponseRedirect(doc.get_absolute_url())
|
||||
|
||||
return render(request, 'doc/draft/resurrect.html',
|
||||
|
@ -842,6 +848,21 @@ def resurrect(request, name):
|
|||
resurrect_requested_by=resurrect_requested_by,
|
||||
back_url=doc.get_absolute_url()))
|
||||
|
||||
|
||||
def restore_draft_file(request, draft):
|
||||
'''restore latest revision document file from archive'''
|
||||
basename = '{}-{}'.format(draft.name, draft.rev)
|
||||
files = glob.glob(os.path.join(settings.INTERNET_DRAFT_ARCHIVE_DIR, basename) + '.*')
|
||||
log.log("Resurrecting %s. Moving files:" % draft.name)
|
||||
for file in files:
|
||||
try:
|
||||
shutil.move(file, settings.INTERNET_DRAFT_PATH)
|
||||
log.log(" Moved file %s to %s" % (file, settings.INTERNET_DRAFT_PATH))
|
||||
except shutil.Error as ex:
|
||||
messages.warning(request, 'There was an error restoring the draft file: {} ({})'.format(file, ex))
|
||||
log.log(" Exception %s when attempting to move %s" % (ex, file))
|
||||
|
||||
|
||||
class IESGNoteForm(forms.Form):
|
||||
note = forms.CharField(widget=forms.Textarea, label="IESG note", required=False, strip=False)
|
||||
|
||||
|
|
Loading…
Reference in a new issue