diff --git a/ietf/submit/forms.py b/ietf/submit/forms.py index e107bdf225..0df001ee69 100644 --- a/ietf/submit/forms.py +++ b/ietf/submit/forms.py @@ -254,6 +254,22 @@ def cleaned_line(self): class ReplacesForm(forms.Form): replaces = SearchableDocAliasesField(required=False, help_text="Any drafts that this document replaces (approval required for replacing a draft you are not the author of)") + def __init__(self, *args, **kwargs): + self.name = kwargs.pop("name") + super(ReplacesForm, self).__init__(*args, **kwargs) + + def clean_replaces(self): + for alias in self.cleaned_data['replaces']: + if alias.document.name == self.name: + raise forms.ValidationError("A draft cannot replace itself.") + if alias.document.type_id != "draft": + raise forms.ValidationError("A draft can only replace another draft") + if alias.document.get_state_slug() == "rfc": + raise forms.ValidationError("A draft cannot replace an RFC") + if alias.document.get_state_slug('draft-iesg') in ('approved','ann','rfcqueue'): + raise forms.ValidationError(alias.name+" is approved by the IESG and cannot be replaced") + return self.cleaned_data['replaces'] + class EditSubmissionForm(forms.ModelForm): title = forms.CharField(required=True, max_length=255) rev = forms.CharField(label=u'Revision', max_length=2, required=True) diff --git a/ietf/submit/tests.py b/ietf/submit/tests.py index f14dcdb6ce..9cc373a3f9 100644 --- a/ietf/submit/tests.py +++ b/ietf/submit/tests.py @@ -102,9 +102,10 @@ def supply_extra_metadata(self, name, status_url, submitter_name, submitter_emai "replaces": replaces, }) - submission = Submission.objects.get(name=name) - self.assertEqual(submission.submitter, u"%s <%s>" % (submitter_name, submitter_email)) - self.assertEqual(submission.replaces, ",".join(d.name for d in DocAlias.objects.filter(pk__in=replaces.split(",") if replaces else []))) + if r.status_code == 302: + submission = Submission.objects.get(name=name) + self.assertEqual(submission.submitter, u"%s <%s>" % (submitter_name, submitter_email)) + self.assertEqual(submission.replaces, ",".join(d.name for d in DocAlias.objects.filter(pk__in=replaces.split(",") if replaces else []))) return r @@ -355,7 +356,7 @@ def test_submit_new_individual(self): self.assertEqual(new_revision.type, "new_revision") self.assertEqual(new_revision.by.name, "Submitter Name") - def test_submit_update_replacing_self(self): + def test_submit_update_individual(self): draft = make_test_data() name = draft.name rev = '%02d'%(int(draft.rev)+1) @@ -363,6 +364,18 @@ def test_submit_update_replacing_self(self): mailbox_before = len(outbox) replaced_alias = draft.docalias_set.first() r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=str(replaced_alias.pk)) + self.assertEqual(r.status_code, 200) + self.assertTrue('cannot replace itself' in r.content) + replaced_alias = DocAlias.objects.get(name='draft-ietf-random-thing') + r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=str(replaced_alias.pk)) + self.assertEqual(r.status_code, 200) + self.assertTrue('cannot replace an RFC' in r.content) + replaced_alias.document.set_state(State.objects.get(type='draft-iesg',slug='approved')) + replaced_alias.document.set_state(State.objects.get(type='draft',slug='active')) + r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=str(replaced_alias.pk)) + self.assertEqual(r.status_code, 200) + self.assertTrue('approved by the IESG and cannot' in r.content) + r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces='') self.assertEqual(r.status_code, 302) status_url = r["Location"] r = self.client.get(status_url) diff --git a/ietf/submit/views.py b/ietf/submit/views.py index 8a6bc56886..1191a4a450 100644 --- a/ietf/submit/views.py +++ b/ietf/submit/views.py @@ -165,7 +165,7 @@ def submission_status(request, submission_id, access_token=None): submitter_form = NameEmailForm(initial=submission.submitter_parsed(), prefix="submitter") - replaces_form = ReplacesForm(initial=DocAlias.objects.filter(name__in=submission.replaces.split(","))) + replaces_form = ReplacesForm(name=submission.name,initial=DocAlias.objects.filter(name__in=submission.replaces.split(","))) if request.method == 'POST': action = request.POST.get('action') @@ -174,7 +174,7 @@ def submission_status(request, submission_id, access_token=None): return HttpResponseForbidden("You do not have permission to perfom this action") submitter_form = NameEmailForm(request.POST, prefix="submitter") - replaces_form = ReplacesForm(request.POST) + replaces_form = ReplacesForm(request.POST, name=submission.name) validations = [submitter_form.is_valid(), replaces_form.is_valid()] if all(validations): submission.submitter = submitter_form.cleaned_line() @@ -311,7 +311,7 @@ def edit_submission(request, submission_id, access_token=None): edit_form = EditSubmissionForm(request.POST, instance=submission, prefix="edit") submitter_form = NameEmailForm(request.POST, prefix="submitter") - replaces_form = ReplacesForm(request.POST) + replaces_form = ReplacesForm(request.POST,name=submission.name) author_forms = [ NameEmailForm(request.POST, email_required=False, prefix=prefix) for prefix in request.POST.getlist("authors-prefix") if prefix != "authors-" ] @@ -352,7 +352,7 @@ def edit_submission(request, submission_id, access_token=None): else: edit_form = EditSubmissionForm(instance=submission, prefix="edit") submitter_form = NameEmailForm(initial=submission.submitter_parsed(), prefix="submitter") - replaces_form = ReplacesForm(initial=DocAlias.objects.filter(name__in=submission.replaces.split(","))) + replaces_form = ReplacesForm(name=submission.name,initial=DocAlias.objects.filter(name__in=submission.replaces.split(","))) author_forms = [ NameEmailForm(initial=author, email_required=False, prefix="authors-%s" % i) for i, author in enumerate(submission.authors_parsed()) ]