Merge pull request #5841 from rjsparks/related_no_alias

feat: Remove DocAlias from RelatedDocument
This commit is contained in:
Jennifer Richards 2023-07-28 15:43:27 -07:00 committed by GitHub
commit 9f0b2b5432
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
54 changed files with 491 additions and 350 deletions

View file

@ -934,7 +934,7 @@ class RfcdiffSupportTests(TestCase):
self.assertNotIn('previous', received, 'Rev 00 has no previous name when not replacing a draft')
replaced = IndividualDraftFactory()
RelatedDocument.objects.create(relationship_id='replaces',source=draft,target=replaced.docalias.first())
RelatedDocument.objects.create(relationship_id='replaces',source=draft,target=replaced)
received = self.getJson(dict(name=draft.name, rev='00'))
self.assertEqual(received['previous'], f'{replaced.name}-{replaced.rev}',
'Rev 00 has a previous name when replacing a draft')
@ -965,7 +965,7 @@ class RfcdiffSupportTests(TestCase):
def do_rfc_test(self, draft_name):
draft = WgDraftFactory(name=draft_name, create_revisions=range(0,2))
rfc = WgRfcFactory(group=draft.group, rfc_number=self.next_rfc_number())
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc.docalias.first())
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc)
draft.set_state(State.objects.get(type_id='draft',slug='rfc'))
draft.set_state(State.objects.get(type_id='draft-iesg', slug='pub'))
draft, rfc = reload_db_objects(draft, rfc)
@ -1017,7 +1017,7 @@ class RfcdiffSupportTests(TestCase):
def test_rfc_with_tombstone(self):
draft = WgDraftFactory(create_revisions=range(0,2))
rfc = WgRfcFactory(rfc_number=3261,group=draft.group)# See views_doc.HAS_TOMBSTONE
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc.docalias.first())
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc)
draft.set_state(State.objects.get(type_id='draft',slug='rfc'))
draft.set_state(State.objects.get(type_id='draft-iesg', slug='pub'))
draft = reload_db_objects(draft)
@ -1029,7 +1029,7 @@ class RfcdiffSupportTests(TestCase):
def do_rfc_with_broken_history_test(self, draft_name):
draft = WgDraftFactory(rev='10', name=draft_name)
rfc = WgRfcFactory(group=draft.group, rfc_number=self.next_rfc_number())
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc.docalias.first())
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc)
draft.set_state(State.objects.get(type_id='draft',slug='rfc'))
draft.set_state(State.objects.get(type_id='draft-iesg', slug='pub'))
draft = reload_db_objects(draft)

View file

@ -344,7 +344,7 @@ def rfcdiff_latest_json(request, name, rev=None):
response['previous'] = f'{draft.name}-{prev_rev}'
response['previous_url'] = get_previous_url(draft.name, prev_rev)
elif doc.type_id == "draft" and not found_rev and doc.relateddocument_set.filter(relationship_id="became_rfc").exists():
rfc = doc.related_that_doc("became_rfc")[0].document
rfc = doc.related_that_doc("became_rfc")[0]
response['content_url'] = rfc.get_href()
response['name']=rfc.name
prev_rev = doc.rev
@ -359,7 +359,7 @@ def rfcdiff_latest_json(request, name, rev=None):
if doc.rev == '00':
replaces_docs = (history.doc if condition=='historic version' else doc).related_that_doc('replaces')
if replaces_docs:
replaces = replaces_docs[0].document
replaces = replaces_docs[0]
response['previous'] = f'{replaces.name}-{replaces.rev}'
response['previous_url'] = get_previous_url(replaces.name, replaces.rev)
else:

View file

@ -43,6 +43,7 @@ class DocActionHolderInline(admin.TabularInline):
class RelatedDocumentInline(admin.TabularInline):
model = RelatedDocument
fk_name= 'source'
def this(self, instance):
return instance.source.canonical_name()
readonly_fields = ['this', ]
@ -125,7 +126,7 @@ admin.site.register(DocReminder, DocReminderAdmin)
class RelatedDocumentAdmin(admin.ModelAdmin):
list_display = ['source', 'target', 'relationship', ]
list_filter = ['relationship', ]
search_fields = ['source__name', 'target__name', 'target__docs__name', ]
search_fields = ['source__name', 'target__name', ]
raw_id_fields = ['source', 'target', ]
admin.site.register(RelatedDocument, RelatedDocumentAdmin)

View file

@ -83,13 +83,7 @@ class BaseDocumentFactory(factory.django.DjangoModelFactory):
def relations(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument
if create and extracted:
for (rel_id, doc) in extracted:
if isinstance(doc, Document):
docalias = doc.docalias.first()
elif isinstance(doc, DocAlias):
docalias = doc
else:
continue
obj.relateddocument_set.create(relationship_id=rel_id, target=docalias)
obj.relateddocument_set.create(relationship_id=rel_id, target=doc)
@factory.post_generation
def create_revisions(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument
@ -244,7 +238,7 @@ class StatusChangeFactory(BaseDocumentFactory):
for (rel, target) in extracted:
obj.relateddocument_set.create(relationship_id=rel,target=target)
else:
obj.relateddocument_set.create(relationship_id='tobcp', target=WgRfcFactory().docalias.first())
obj.relateddocument_set.create(relationship_id='tobcp', target=WgRfcFactory())
@factory.post_generation
def states(obj, create, extracted, **kwargs):
@ -271,9 +265,9 @@ class ConflictReviewFactory(BaseDocumentFactory):
if not create:
return
if extracted:
obj.relateddocument_set.create(relationship_id='conflrev',target=extracted.docalias.first())
obj.relateddocument_set.create(relationship_id='conflrev',target=extracted)
else:
obj.relateddocument_set.create(relationship_id='conflrev',target=DocumentFactory(name=obj.name.replace('conflict-review-','draft-'),type_id='draft',group=Group.objects.get(type_id='individ')).docalias.first())
obj.relateddocument_set.create(relationship_id='conflrev',target=DocumentFactory(name=obj.name.replace('conflict-review-','draft-'),type_id='draft',group=Group.objects.get(type_id='individ')))
@factory.post_generation

View file

@ -8,7 +8,7 @@ from django import forms
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.core.validators import validate_email
from ietf.doc.fields import SearchableDocAliasesField, SearchableDocAliasField
from ietf.doc.fields import SearchableDocumentField, SearchableDocumentsField
from ietf.doc.models import RelatedDocument, DocExtResource
from ietf.iesg.models import TelechatDate
from ietf.iesg.utils import telechat_page_count
@ -134,11 +134,11 @@ class ActionHoldersForm(forms.Form):
IESG_APPROVED_STATE_LIST = ("ann", "rfcqueue", "pub")
class AddDownrefForm(forms.Form):
rfc = SearchableDocAliasField(
rfc = SearchableDocumentField(
label="Referenced RFC",
help_text="The RFC that is approved for downref",
required=True)
drafts = SearchableDocAliasesField(
drafts = SearchableDocumentsField(
label="Internet-Drafts that makes the reference",
help_text="The Internet-Drafts that approve the downref in their Last Call",
required=True)
@ -148,7 +148,7 @@ class AddDownrefForm(forms.Form):
raise forms.ValidationError("Please provide a referenced RFC and a referencing Internet-Draft")
rfc = self.cleaned_data['rfc']
if rfc.document.type_id != "rfc":
if rfc.type_id != "rfc":
raise forms.ValidationError("Cannot find the RFC: " + rfc.name)
return rfc
@ -158,10 +158,10 @@ class AddDownrefForm(forms.Form):
v_err_names = []
drafts = self.cleaned_data['drafts']
for da in drafts:
state = da.document.get_state("draft-iesg")
for d in drafts:
state = d.get_state("draft-iesg")
if not state or state.slug not in IESG_APPROVED_STATE_LIST:
v_err_names.append(da.name)
v_err_names.append(d.name)
if v_err_names:
raise forms.ValidationError("Internet-Draft is not yet approved: " + ", ".join(v_err_names))
return drafts
@ -173,23 +173,23 @@ class AddDownrefForm(forms.Form):
v_err_pairs = []
rfc = self.cleaned_data['rfc']
drafts = self.cleaned_data['drafts']
for da in drafts:
if RelatedDocument.objects.filter(source=da.document, target=rfc, relationship_id='downref-approval'):
v_err_pairs.append(f"{da.name} --> RFC {rfc.document.rfc_number}")
for d in drafts:
if RelatedDocument.objects.filter(source=d, target=rfc, relationship_id='downref-approval'):
v_err_pairs.append(f"{d.name} --> RFC {rfc.rfc_number}")
if v_err_pairs:
raise forms.ValidationError("Downref is already in the registry: " + ", ".join(v_err_pairs))
if 'save_downref_anyway' not in self.data:
# this check is skipped if the save_downref_anyway button is used
v_err_refnorm = ""
for da in drafts:
if not RelatedDocument.objects.filter(source=da.document, target=rfc, relationship_id='refnorm'):
for d in drafts:
if not RelatedDocument.objects.filter(source=d, target=rfc, relationship_id='refnorm'):
if v_err_refnorm:
v_err_refnorm = v_err_refnorm + " or " + da.name
v_err_refnorm = v_err_refnorm + " or " + d.name
else:
v_err_refnorm = da.name
v_err_refnorm = d.name
if v_err_refnorm:
v_err_refnorm_prefix = f"There does not seem to be a normative reference to RFC {rfc.document.rfc_number} by "
v_err_refnorm_prefix = f"There does not seem to be a normative reference to RFC {rfc.rfc_number} by "
raise forms.ValidationError(v_err_refnorm_prefix + v_err_refnorm)

View file

@ -54,7 +54,7 @@ def email_ad_approved_doc(request, doc, text):
def email_ad_approved_conflict_review(request, review, ok_to_publish):
"""Email notification when AD approves a conflict review"""
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target.document
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target
(to, cc) = gather_address_lists("ad_approved_conflict_review")
frm = request.user.person.formatted_email()
send_mail(request,

View file

@ -130,9 +130,8 @@ class Command(BaseCommand):
for draft in interesting_drafts.distinct().iterator():
# Omit drafts that became RFCs, unless they were published in the last DEFAULT_YEARS
if draft.get_state_slug()=="rfc":
rfc_alias = next(iter(draft.related_that_doc("became_rfc")), None)
log.assertion("rfc_alias is not None")
rfc = rfc_alias.document
rfc = next(iter(draft.related_that_doc("became_rfc")), None)
log.assertion("rfc is not None")
if rfc.latest_event(type='published_rfc').time < show_since:
continue

View file

@ -0,0 +1,77 @@
# Generated by Django 4.2.2 on 2023-06-16 13:40
from django.db import migrations
import django.db.models.deletion
from django.db.models import F, Subquery, OuterRef
import ietf.utils.models
def forward(apps, schema_editor):
RelatedDocument = apps.get_model("doc", "RelatedDocument")
DocAlias = apps.get_model("doc", "DocAlias")
subquery = Subquery(DocAlias.objects.filter(pk=OuterRef("deprecated_target")).values("docs")[:1])
RelatedDocument.objects.annotate(firstdoc=subquery).update(target=F("firstdoc"))
def reverse(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
("doc", "0010_move_rfc_docaliases"),
]
operations = [
migrations.AlterField(
model_name='relateddocument',
name='target',
field=ietf.utils.models.ForeignKey(
db_index=False,
on_delete=django.db.models.deletion.CASCADE,
to='doc.docalias',
),
),
migrations.RenameField(
model_name="relateddocument",
old_name="target",
new_name="deprecated_target"
),
migrations.AlterField(
model_name='relateddocument',
name='deprecated_target',
field=ietf.utils.models.ForeignKey(
db_index=True,
on_delete=django.db.models.deletion.CASCADE,
to='doc.docalias',
),
),
migrations.AddField(
model_name="relateddocument",
name="target",
field=ietf.utils.models.ForeignKey(
default=1, # A lie, but a convenient one - no relations point here.
on_delete=django.db.models.deletion.CASCADE,
related_name="targets_related",
to="doc.document",
db_index=False,
),
preserve_default=False,
),
migrations.RunPython(forward, reverse),
migrations.AlterField(
model_name="relateddocument",
name="target",
field=ietf.utils.models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="targets_related",
to="doc.document",
db_index=True,
),
),
migrations.RemoveField(
model_name="relateddocument",
name="deprecated_target",
field=ietf.utils.models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to='doc.DocAlias',
),
),
]

View file

@ -0,0 +1,80 @@
# Generated by Django 4.2.2 on 2023-06-16 13:40
from django.db import migrations
import django.db.models.deletion
from django.db.models import F, Subquery, OuterRef
import ietf.utils.models
def forward(apps, schema_editor):
RelatedDocHistory = apps.get_model("doc", "RelatedDocHistory")
DocAlias = apps.get_model("doc", "DocAlias")
subquery = Subquery(DocAlias.objects.filter(pk=OuterRef("deprecated_target")).values("docs")[:1])
RelatedDocHistory.objects.annotate(firstdoc=subquery).update(target=F("firstdoc"))
def reverse(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
("doc", "0011_relate_no_aliases"),
]
operations = [
migrations.AlterField(
model_name='relateddochistory',
name='target',
field=ietf.utils.models.ForeignKey(
db_index=False,
on_delete=django.db.models.deletion.CASCADE,
to='doc.docalias',
related_name='reversely_related_document_history_set',
),
),
migrations.RenameField(
model_name="relateddochistory",
old_name="target",
new_name="deprecated_target"
),
migrations.AlterField(
model_name='relateddochistory',
name='deprecated_target',
field=ietf.utils.models.ForeignKey(
db_index=True,
on_delete=django.db.models.deletion.CASCADE,
to='doc.docalias',
related_name='deprecated_reversely_related_document_history_set',
),
),
migrations.AddField(
model_name="relateddochistory",
name="target",
field=ietf.utils.models.ForeignKey(
default=1, # A lie, but a convenient one - no relations point here.
on_delete=django.db.models.deletion.CASCADE,
to="doc.document",
db_index=False,
related_name='reversely_related_document_history_set',
),
preserve_default=False,
),
migrations.RunPython(forward, reverse),
migrations.AlterField(
model_name="relateddochistory",
name="target",
field=ietf.utils.models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="doc.document",
db_index=True,
related_name='reversely_related_document_history_set',
),
),
migrations.RemoveField(
model_name="relateddochistory",
name="deprecated_target",
field=ietf.utils.models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to='doc.DocAlias',
related_name='deprecated_reversely_related_document_history_set',
),
),
]

View file

@ -453,9 +453,9 @@ class DocumentInfo(models.Model):
if not isinstance(relationship, tuple):
raise TypeError("Expected a string or tuple, received %s" % type(relationship))
if isinstance(self, Document):
return RelatedDocument.objects.filter(target__docs=self, relationship__in=relationship).select_related('source')
return RelatedDocument.objects.filter(target=self, relationship__in=relationship).select_related('source')
elif isinstance(self, DocHistory):
return RelatedDocHistory.objects.filter(target__docs=self.doc, relationship__in=relationship).select_related('source')
return RelatedDocHistory.objects.filter(target=self.doc, relationship__in=relationship).select_related('source')
else:
raise TypeError("Expected method called on Document or DocHistory")
@ -489,8 +489,7 @@ class DocumentInfo(models.Model):
for r in rels:
if not r in related:
related += ( r, )
for doc in r.target.docs.all():
related = doc.all_relations_that_doc(relationship, related)
related = r.target.all_relations_that_doc(relationship, related)
return related
def related_that(self, relationship):
@ -663,7 +662,7 @@ STATUSCHANGE_RELATIONS = ('tops','tois','tohist','toinf','tobcp','toexp')
class RelatedDocument(models.Model):
source = ForeignKey('Document')
target = ForeignKey('DocAlias')
target = ForeignKey('Document', related_name='targets_related')
relationship = ForeignKey(DocRelationshipName)
def action(self):
return self.relationship.name
@ -686,16 +685,16 @@ class RelatedDocument(models.Model):
if source_lvl not in ['bcp','ps','ds','std']:
return None
if self.target.document.type_id == 'rfc':
if not self.target.document.std_level:
if self.target.type_id == 'rfc':
if not self.target.std_level:
target_lvl = 'unkn'
else:
target_lvl = self.target.document.std_level.slug
target_lvl = self.target.std_level.slug
else:
if not self.target.document.intended_std_level:
if not self.target.intended_std_level:
target_lvl = 'unkn'
else:
target_lvl = self.target.document.intended_std_level.slug
target_lvl = self.target.intended_std_level.slug
rank = { 'ps':1, 'ds':2, 'std':3, 'bcp':3 }
@ -709,7 +708,7 @@ class RelatedDocument(models.Model):
def is_approved_downref(self):
if self.target.document.type_id == "rfc":
if self.target.type_id == 'rfc':
if RelatedDocument.objects.filter(relationship_id='downref-approval', target=self.target).exists():
return "Approved Downref"
@ -962,7 +961,15 @@ class Document(DocumentInfo):
document directly or indirectly obsoletes or replaces
"""
from ietf.ipr.models import IprDocRel
iprs = IprDocRel.objects.filter(document__in=list(self.docalias.all())+self.all_related_that_doc(('obs','replaces'))).filter(disclosure__state__in=('posted','removed')).values_list('disclosure', flat=True).distinct()
iprs = (
IprDocRel.objects.filter(
document__in=list(self.docalias.all())
+ [x.docalias.first() for x in self.all_related_that_doc(("obs", "replaces"))] # this really is docalias until IprDocRel changes
)
.filter(disclosure__state__in=("posted", "removed"))
.values_list("disclosure", flat=True)
.distinct()
)
return iprs
def future_presentations(self):
@ -1101,7 +1108,7 @@ class DocExtResource(ExtResource):
class RelatedDocHistory(models.Model):
source = ForeignKey('DocHistory')
target = ForeignKey('DocAlias', related_name="reversely_related_document_history_set")
target = ForeignKey('Document', related_name="reversely_related_document_history_set")
relationship = ForeignKey(DocRelationshipName)
def __str__(self):
return u"%s %s %s" % (self.source.doc.name, self.relationship.name.lower(), self.target.name)

View file

@ -288,8 +288,8 @@ def urlize_related_target_list(related, document_html=False):
"""Convert a list of RelatedDocuments into list of links using the target document's canonical name"""
links = []
for rel in related:
name=rel.target.document.canonical_name()
title = rel.target.document.title
name=rel.target.canonical_name()
title = rel.target.title
url = urlreverse('ietf.doc.views_doc.document_main' if document_html is False else 'ietf.doc.views_doc.document_html', kwargs=dict(name=name))
name = escape(name)
title = escape(title)

View file

@ -624,7 +624,15 @@ Man Expires September 22, 2015 [Page 3]
# Docs for testing relationships. Does not test 'possibly-replaces'. The 'replaced_by' direction
# is tested separately below.
replaced = IndividualDraftFactory()
draft.relateddocument_set.create(relationship_id='replaces',source=draft,target=replaced.docalias.first())
draft.relateddocument_set.create(relationship_id='replaces',source=draft,target=replaced)
obsoleted = IndividualDraftFactory()
draft.relateddocument_set.create(relationship_id='obs',source=draft,target=obsoleted)
obsoleted_by = IndividualDraftFactory()
obsoleted_by.relateddocument_set.create(relationship_id='obs',source=obsoleted_by,target=draft)
updated = IndividualDraftFactory()
draft.relateddocument_set.create(relationship_id='updates',source=draft,target=updated)
updated_by = IndividualDraftFactory()
updated_by.relateddocument_set.create(relationship_id='updates',source=obsoleted_by,target=draft)
DocExtResourceFactory(doc=draft)
@ -746,7 +754,7 @@ Man Expires September 22, 2015 [Page 3]
shepherd_id=draft.shepherd_id, ad_id=draft.ad_id, expires=draft.expires,
notify=draft.notify, note=draft.note)
rel = RelatedDocument.objects.create(source=replacement,
target=draft.docalias.get(name__startswith="draft"),
target=draft,
relationship_id="replaces")
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)))
@ -763,16 +771,16 @@ Man Expires September 22, 2015 [Page 3]
rfc = WgRfcFactory(group=draft.group, name="rfc123456")
rfc.save_with_history([DocEvent.objects.create(doc=rfc, rev=None, type="published_rfc", by=Person.objects.get(name="(System)"))])
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc.docalias.first())
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc)
obsoleted = IndividualRfcFactory()
rfc.relateddocument_set.create(relationship_id='obs',target=obsoleted.docalias.first())
rfc.relateddocument_set.create(relationship_id='obs',target=obsoleted)
obsoleted_by = IndividualRfcFactory()
obsoleted_by.relateddocument_set.create(relationship_id='obs',target=rfc.docalias.first())
obsoleted_by.relateddocument_set.create(relationship_id='obs',target=rfc)
updated = IndividualRfcFactory()
rfc.relateddocument_set.create(relationship_id='updates',target=updated.docalias.first())
rfc.relateddocument_set.create(relationship_id='updates',target=updated)
updated_by = IndividualRfcFactory()
updated_by.relateddocument_set.create(relationship_id='updates',target=rfc.docalias.first())
updated_by.relateddocument_set.create(relationship_id='updates',target=rfc)
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)))
self.assertEqual(r.status_code, 302)
@ -821,7 +829,7 @@ Man Expires September 22, 2015 [Page 3]
draft = WgRfcFactory()
status_change_doc = StatusChangeFactory(
group=draft.group,
changes_status_of=[('tops', draft.docalias.first())],
changes_status_of=[('tops', draft)],
)
status_change_url = urlreverse(
'ietf.doc.views_doc.document_main',
@ -829,7 +837,7 @@ Man Expires September 22, 2015 [Page 3]
)
proposed_status_change_doc = StatusChangeFactory(
group=draft.group,
changes_status_of=[('tobcp', draft.docalias.first())],
changes_status_of=[('tobcp', draft)],
states=[State.objects.get(slug='needshep', type='statchg')],
)
proposed_status_change_url = urlreverse(
@ -1422,7 +1430,7 @@ Man Expires September 22, 2015 [Page 3]
rfc = WgRfcFactory(group=group)
draft = WgDraftFactory(group=group)
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc.docalias.first())
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc)
DocEventFactory.create(doc=rfc, type='published_rfc', time=event_datetime)
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=rfc.name)))
self.assertEqual(r.status_code, 200)
@ -1437,7 +1445,7 @@ Man Expires September 22, 2015 [Page 3]
rfc = WgRfcFactory(group=group)
draft = WgDraftFactory(name='draft-rfc-document-%s'% group_type_id, group=group)
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc.docalias.first())
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc)
DocEventFactory.create(doc=rfc, type='published_rfc', time=event_datetime)
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=rfc.name)))
self.assertEqual(r.status_code, 200)
@ -1540,7 +1548,7 @@ class DocTestCase(TestCase):
statchg = StatusChangeFactory()
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=statchg.name)))
self.assertEqual(r.status_code, 200)
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=statchg.relateddocument_set.first().target.document.name)))
r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=statchg.relateddocument_set.first().target)))
self.assertEqual(r.status_code, 200)
def test_document_charter(self):
@ -1701,8 +1709,8 @@ class DocTestCase(TestCase):
self.assertNotContains(r, 'more YES or NO')
# status change
DocAlias.objects.create(name='rfc9998').docs.add(IndividualDraftFactory())
DocAlias.objects.create(name='rfc9999').docs.add(IndividualDraftFactory())
Document.objects.create(name='rfc9998')
Document.objects.create(name='rfc9999')
doc = DocumentFactory(type_id='statchg',name='status-change-imaginary-mid-review')
iesgeval_pk = str(State.objects.get(slug='iesgeval',type__slug='statchg').pk)
empty_outbox()
@ -1715,12 +1723,12 @@ class DocTestCase(TestCase):
self.assertIn('iesg-secretary',outbox[0]['To'])
self.assertIn('drafts-eval',outbox[1]['To'])
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9998'),relationship_id='tohist')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9998'),relationship_id='tohist')
r = self.client.get(urlreverse("ietf.doc.views_doc.document_ballot", kwargs=dict(name=doc.name)))
self.assertNotContains(r, 'Needs a YES')
self.assertNotContains(r, 'more YES or NO')
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9999'),relationship_id='tois')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9999'),relationship_id='tois')
r = self.client.get(urlreverse("ietf.doc.views_doc.document_ballot", kwargs=dict(name=doc.name)))
self.assertContains(r, 'more YES or NO')
@ -2037,7 +2045,7 @@ class ReferencesTest(TestCase):
def test_references(self):
doc1 = WgDraftFactory(name='draft-ietf-mars-test')
doc2 = IndividualDraftFactory(name='draft-imaginary-independent-submission').docalias.first()
doc2 = IndividualDraftFactory(name='draft-imaginary-independent-submission')
RelatedDocument.objects.get_or_create(source=doc1,target=doc2,relationship=DocRelationshipName.objects.get(slug='refnorm'))
url = urlreverse('ietf.doc.views_doc.document_references', kwargs=dict(name=doc1.name))
r = self.client.get(url)
@ -2103,7 +2111,7 @@ class GenerateDraftAliasesTests(TestCase):
rfc3 = WgRfcFactory()
DocEventFactory.create(doc=rfc3, type="published_rfc", time=a_month_ago)
doc3.relateddocument_set.create(
relationship_id="became_rfc", target=rfc3.docalias.first()
relationship_id="became_rfc", target=rfc3
)
doc4 = WgDraftFactory.create(
authors=[author4, author5],
@ -2119,7 +2127,7 @@ class GenerateDraftAliasesTests(TestCase):
time=datetime.datetime(2010, 10, 10, tzinfo=RPC_TZINFO),
)
doc4.relateddocument_set.create(
relationship_id="became_rfc", target=rfc4.docalias.first()
relationship_id="became_rfc", target=rfc4
)
doc5 = IndividualDraftFactory(authors=[author6])
@ -2673,7 +2681,7 @@ class Idnits2SupportTests(TestCase):
def test_idnits2_state(self):
rfc = WgRfcFactory()
draft = WgDraftFactory()
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc.docalias.first())
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc)
url = urlreverse('ietf.doc.views_doc.idnits2_state', kwargs=dict(name=rfc.canonical_name()))
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
@ -2760,7 +2768,7 @@ class PdfizedTests(TestCase):
def test_pdfized(self):
rfc = WgRfcFactory()
draft = WgDraftFactory(create_revisions=range(0,2))
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc.docalias.first())
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc)
dir = settings.RFC_PATH
with (Path(dir) / f'{rfc.name}.txt').open('w') as f:

View file

@ -803,8 +803,8 @@ class ApproveBallotTests(TestCase):
desc='Last call announcement was changed',
text='this is simple last call text.' )
rfc = IndividualRfcFactory.create(
name = "rfc6666",
stream_id='ise',
other_aliases=['rfc6666',],
states=[('draft','rfc'),('draft-iesg','pub')],
std_level_id='inf', )
@ -821,7 +821,7 @@ class ApproveBallotTests(TestCase):
self.assertContains(r, "No downward references for")
# Add a downref, the page should ask if it should be added to the registry
rel = draft.relateddocument_set.create(target=rfc.docalias.get(name='rfc6666'),relationship_id='refnorm')
rel = draft.relateddocument_set.create(target=rfc, relationship_id='refnorm')
d = [rdoc for rdoc in draft.relateddocument_set.all() if rel.is_approved_downref()]
original_len = len(d)
r = self.client.get(url)
@ -1127,7 +1127,7 @@ class RegenerateLastCallTestCase(TestCase):
std_level_id='inf',
)
draft.relateddocument_set.create(target=rfc.docalias.get(name='rfc6666'),relationship_id='refnorm')
draft.relateddocument_set.create(target=rfc,relationship_id='refnorm')
r = self.client.post(url, dict(regenerate_last_call_text="1"))
self.assertEqual(r.status_code, 200)
@ -1137,7 +1137,7 @@ class RegenerateLastCallTestCase(TestCase):
self.assertTrue("rfc6666" in lc_text)
self.assertTrue("Independent Submission" in lc_text)
draft.relateddocument_set.create(target=rfc.docalias.get(name='rfc6666'), relationship_id='downref-approval')
draft.relateddocument_set.create(target=rfc, relationship_id='downref-approval')
r = self.client.post(url, dict(regenerate_last_call_text="1"))
self.assertEqual(r.status_code, 200)

View file

@ -70,12 +70,12 @@ class ConflictReviewTests(TestCase):
self.assertEqual(review_doc.ad.name,'Areað Irector')
self.assertEqual(review_doc.notify,'ipu@ietf.org')
doc = Document.objects.get(name='draft-imaginary-independent-submission')
self.assertTrue(doc in [x.target.document for x in review_doc.relateddocument_set.filter(relationship__slug='conflrev')])
self.assertTrue(doc in [x.target for x in review_doc.relateddocument_set.filter(relationship__slug='conflrev')])
self.assertTrue(review_doc.latest_event(DocEvent,type="added_comment").desc.startswith("IETF conflict review requested"))
self.assertTrue(doc.latest_event(DocEvent,type="added_comment").desc.startswith("IETF conflict review initiated"))
self.assertTrue('Conflict Review requested' in outbox[-1]['Subject'])
# verify you can't start a review when a review is already in progress
r = self.client.post(url,dict(ad="Areað Irector",create_in_state="Needs Shepherd",notify='ipu@ietf.org'))
self.assertEqual(r.status_code, 404)
@ -119,7 +119,7 @@ class ConflictReviewTests(TestCase):
self.assertEqual(review_doc.ad.name,'Ietf Chair')
self.assertEqual(review_doc.notify,'ipu@ietf.org')
doc = Document.objects.get(name='draft-imaginary-independent-submission')
self.assertTrue(doc in [x.target.document for x in review_doc.relateddocument_set.filter(relationship__slug='conflrev')])
self.assertTrue(doc in [x.target for x in review_doc.relateddocument_set.filter(relationship__slug='conflrev')])
self.assertEqual(len(outbox), messages_before + 2)

View file

@ -24,7 +24,7 @@ class Downref(TestCase):
self.docalias = self.doc.docalias.get(name='draft-ietf-mars-approved-document')
self.rfc = WgRfcFactory(rfc_number=9998)
self.rfcalias = self.rfc.docalias.get(name='rfc9998')
RelatedDocument.objects.create(source=self.doc, target=self.rfcalias, relationship_id='downref-approval')
RelatedDocument.objects.create(source=self.doc, target=self.rfc, relationship_id='downref-approval')
def test_downref_registry(self):
url = urlreverse('ietf.doc.views_downref.downref_registry')
@ -64,36 +64,36 @@ class Downref(TestCase):
self.assertContains(r, 'Save downref')
# error - already in the downref registry
r = self.client.post(url, dict(rfc=self.rfcalias.pk, drafts=(self.docalias.pk, )))
r = self.client.post(url, dict(rfc=self.rfc.pk, drafts=(self.doc.pk, )))
self.assertContains(r, 'Downref is already in the registry')
# error - source is not in an approved state
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
r = self.client.post(url, dict(rfc=self.rfcalias.pk, drafts=(self.draftalias.pk, )))
r = self.client.post(url, dict(rfc=self.rfc.pk, drafts=(self.draft.pk, )))
self.assertContains(r, 'Draft is not yet approved')
# error - the target is not a normative reference of the source
self.draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="pub"))
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
r = self.client.post(url, dict(rfc=self.rfcalias.pk, drafts=(self.draftalias.pk, )))
r = self.client.post(url, dict(rfc=self.rfc.pk, drafts=(self.draft.pk, )))
self.assertContains(r, 'There does not seem to be a normative reference to RFC')
self.assertContains(r, 'Save downref anyway')
# normal - approve the document so the downref is now okay
RelatedDocument.objects.create(source=self.draft, target=self.rfcalias, relationship_id='refnorm')
RelatedDocument.objects.create(source=self.draft, target=self.rfc, relationship_id='refnorm')
draft_de_count_before = self.draft.docevent_set.count()
rfc_de_count_before = self.rfc.docevent_set.count()
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
r = self.client.post(url, dict(rfc=self.rfcalias.pk, drafts=(self.draftalias.pk, )))
r = self.client.post(url, dict(rfc=self.rfc.pk, drafts=(self.draft.pk, )))
self.assertEqual(r.status_code, 302)
newurl = urlreverse('ietf.doc.views_downref.downref_registry')
r = self.client.get(newurl)
self.assertContains(r, '<a href="/doc/draft-ietf-mars-test')
self.assertTrue(RelatedDocument.objects.filter(source=self.draft, target=self.rfcalias, relationship_id='downref-approval'))
self.assertTrue(RelatedDocument.objects.filter(source=self.draft, target=self.rfc, relationship_id='downref-approval'))
self.assertEqual(self.draft.docevent_set.count(), draft_de_count_before + 1)
self.assertEqual(self.rfc.docevent_set.count(), rfc_de_count_before + 1)
@ -101,7 +101,7 @@ class Downref(TestCase):
draft = WgDraftFactory(name='draft-ietf-mars-ready-for-lc-document',intended_std_level_id='ps',states=[('draft-iesg','iesg-eva')])
WgDraftFactory(name='draft-ietf-mars-another-approved-document',states=[('draft-iesg','rfcqueue')])
rfc9999 = WgRfcFactory(rfc_number=9999, std_level_id=None)
RelatedDocument.objects.create(source=draft, target=rfc9999.docalias.get(name='rfc9999'), relationship_id='refnorm')
RelatedDocument.objects.create(source=draft, target=rfc9999, relationship_id='refnorm')
url = urlreverse('ietf.doc.views_ballot.lastcalltext', kwargs=dict(name=draft.name))
login_testing_unauthorized(self, "secretary", url)
@ -113,7 +113,7 @@ class Downref(TestCase):
self.assertIn('The document contains these normative downward references', text)
# now, the announcement text about the downref to RFC 9999 should be gone
RelatedDocument.objects.create(source=draft, target=rfc9999.docalias.get(name='rfc9999'),relationship_id='downref-approval')
RelatedDocument.objects.create(source=draft, target=rfc9999, relationship_id='downref-approval')
r = self.client.post(url, dict(regenerate_last_call_text="1"))
self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)

View file

@ -2017,10 +2017,10 @@ class ChangeReplacesTests(TestCase):
# Post that says replacea replaces base a
empty_outbox()
RelatedDocument.objects.create(source=self.replacea, target=self.basea.docalias.first(),
RelatedDocument.objects.create(source=self.replacea, target=self.basea,
relationship=DocRelationshipName.objects.get(slug="possibly-replaces"))
self.assertEqual(self.basea.get_state().slug,'active')
r = self.client.post(url, dict(replaces=self.basea.docalias.first().pk))
r = self.client.post(url, dict(replaces=self.basea.pk))
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')
@ -2034,7 +2034,7 @@ class ChangeReplacesTests(TestCase):
# Post that says replaceboth replaces both base a and base b
url = urlreverse('ietf.doc.views_draft.replaces', kwargs=dict(name=self.replaceboth.name))
self.assertEqual(self.baseb.get_state().slug,'expired')
r = self.client.post(url, dict(replaces=[self.basea.docalias.first().pk, self.baseb.docalias.first().pk]))
r = self.client.post(url, dict(replaces=[self.basea.pk, self.baseb.pk]))
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')
@ -2065,7 +2065,7 @@ class ChangeReplacesTests(TestCase):
def test_review_possibly_replaces(self):
replaced = self.basea.docalias.first()
replaced = self.basea
RelatedDocument.objects.create(source=self.replacea, target=replaced,
relationship=DocRelationshipName.objects.get(slug="possibly-replaces"))
@ -2093,7 +2093,7 @@ class MoreReplacesTests(TestCase):
new_doc = IndividualDraftFactory(stream_id=stream)
url = urlreverse('ietf.doc.views_draft.replaces', kwargs=dict(name=new_doc.name))
r = self.client.post(url, dict(replaces=old_doc.docalias.first().pk))
r = self.client.post(url, dict(replaces=old_doc.pk))
self.assertEqual(r.status_code,302)
old_doc = Document.objects.get(name=old_doc.name)
self.assertEqual(old_doc.get_state_slug('draft'),'repl')

View file

@ -161,8 +161,8 @@ class ReviewTests(TestCase):
# check we can fish it out
old_doc = WgDraftFactory(name="draft-foo-mars-test")
older_doc = WgDraftFactory(name="draft-older")
RelatedDocument.objects.create(source=old_doc, target=older_doc.docalias.first(), relationship_id='replaces')
RelatedDocument.objects.create(source=doc, target=old_doc.docalias.first(), relationship_id='replaces')
RelatedDocument.objects.create(source=old_doc, target=older_doc, relationship_id='replaces')
RelatedDocument.objects.create(source=doc, target=old_doc, relationship_id='replaces')
review_req.doc = older_doc
review_req.save()

View file

@ -15,7 +15,7 @@ from django.conf import settings
from django.urls import reverse as urlreverse
from ietf.doc.factories import DocumentFactory, IndividualRfcFactory, WgRfcFactory, WgDraftFactory
from ietf.doc.models import ( Document, DocAlias, State, DocEvent,
from ietf.doc.models import ( Document, State, DocEvent,
BallotPositionDocEvent, NewRevisionDocEvent, TelechatDocEvent, WriteupDocEvent )
from ietf.doc.utils import create_ballot_if_not_open
from ietf.doc.views_status_change import default_approval_text
@ -74,7 +74,7 @@ class StatusChangeTests(TestCase):
self.assertEqual(status_change.rev,'00')
self.assertEqual(status_change.ad.name,'Areað Irector')
self.assertEqual(status_change.notify,'ipu@ietf.org')
self.assertTrue(status_change.relateddocument_set.filter(relationship__slug='tois',target__docs__name='rfc9999'))
self.assertTrue(status_change.relateddocument_set.filter(relationship__slug='tois',target__name='rfc9999'))
# Verify that it's possible to start a status change without a responsible ad.
r = self.client.post(url,dict(
@ -159,8 +159,8 @@ class StatusChangeTests(TestCase):
self.assertTrue(doc.latest_event(DocEvent,type="added_comment").desc.startswith('Notification list changed'))
# Some additional setup so there's something to put in a generated notify list
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9999'),relationship_id='tois')
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9998'),relationship_id='tohist')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9999'),relationship_id='tois')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9998'),relationship_id='tohist')
# Ask the form to regenerate the list
r = self.client.post(url,dict(regenerate_addresses="1"))
@ -263,8 +263,8 @@ class StatusChangeTests(TestCase):
login_testing_unauthorized(self, "ad", url)
# additional setup
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9999'),relationship_id='tois')
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9998'),relationship_id='tohist')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9999'),relationship_id='tois')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9998'),relationship_id='tohist')
doc.ad = Person.objects.get(name='Ad No2')
doc.save_with_history([DocEvent.objects.create(doc=doc, rev=doc.rev, type="changed_document", by=Person.objects.get(user__username="secretary"), desc="Test")])
@ -307,8 +307,8 @@ class StatusChangeTests(TestCase):
login_testing_unauthorized(self, "secretary", url)
# Some additional setup
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9999'),relationship_id='tois')
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9998'),relationship_id='tohist')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9999'),relationship_id='tois')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9998'),relationship_id='tohist')
create_ballot_if_not_open(None, doc, Person.objects.get(user__username="secretary"), "statchg")
doc.set_state(State.objects.get(slug='appr-pend',type='statchg'))
@ -348,10 +348,10 @@ class StatusChangeTests(TestCase):
url = urlreverse('ietf.doc.views_status_change.change_state',kwargs=dict(name=doc.name))
# Add some status change related documents
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9999'),relationship_id='tois')
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9998'),relationship_id='tohist')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9999'),relationship_id='tois')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9998'),relationship_id='tohist')
# And a non-status change related document
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc14'),relationship_id='updates')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc14'),relationship_id='updates')
login_testing_unauthorized(self, role, url)
empty_outbox()
@ -373,9 +373,9 @@ class StatusChangeTests(TestCase):
self.assertTrue(notification['Subject'].startswith('Approved:'))
notification_text = get_payload_text(notification)
self.assertIn('The AD has approved changing the status', notification_text)
self.assertIn(DocAlias.objects.get(name='rfc9999').document.canonical_name(), notification_text)
self.assertIn(DocAlias.objects.get(name='rfc9998').document.canonical_name(), notification_text)
self.assertNotIn(DocAlias.objects.get(name='rfc14').document.canonical_name(), notification_text)
self.assertIn(Document.objects.get(name='rfc9999').canonical_name(), notification_text)
self.assertIn(Document.objects.get(name='rfc9998').canonical_name(), notification_text)
self.assertNotIn(Document.objects.get(name='rfc14').canonical_name(), notification_text)
self.assertNotIn('No value found for', notification_text) # make sure all interpolation values were set
else:
self.assertEqual(len(outbox), 0)
@ -395,8 +395,8 @@ class StatusChangeTests(TestCase):
login_testing_unauthorized(self, "secretary", url)
# Some additional setup
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9999'),relationship_id='tois')
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9998'),relationship_id='tohist')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9999'),relationship_id='tois')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9998'),relationship_id='tohist')
# get
r = self.client.get(url)
@ -453,11 +453,11 @@ class StatusChangeTests(TestCase):
rfc = WgRfcFactory(rfc_number=9999,std_level_id='ps')
draft = WgDraftFactory(name='draft-ietf-random-thing')
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc.docalias.first())
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc)
rfc = WgRfcFactory(rfc_number=9998,std_level_id='inf')
draft = WgDraftFactory(name='draft-ietf-random-other-thing')
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc.docalias.first())
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc)
DocumentFactory(type_id='statchg',name='status-change-imaginary-mid-review',notify='notify@example.org')

View file

@ -253,7 +253,7 @@ class MiscTests(TestCase):
def do_fuzzy_find_documents_rfc_test(self, name):
draft = WgDraftFactory(name=name, create_revisions=(0, 1, 2))
rfc = WgRfcFactory()
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc.docalias.first())
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc)
draft, rfc = reload_db_objects(draft, rfc)
# by canonical name
@ -327,14 +327,14 @@ class RebuildReferenceRelationsTests(TestCase):
super().setUp()
self.doc = WgDraftFactory() # document under test
# Other documents that should be found by rebuild_reference_relations
self.normative, self.informative, self.unknown = WgRfcFactory.create_batch(3)
self.normative, self.informative, self.unknown = WgRfcFactory.create_batch(3) # AMHERE - these need to have rfc names.
for relationship in ['refnorm', 'refinfo', 'refunk', 'refold']:
self.doc.relateddocument_set.create(
target=WgRfcFactory().docalias.first(),
target=WgRfcFactory(),
relationship_id=relationship,
)
self.updated = WgRfcFactory() # related document that should be left alone
self.doc.relateddocument_set.create(target=self.updated.docalias.first(), relationship_id='updates')
self.doc.relateddocument_set.create(target=self.updated, relationship_id='updates')
self.assertCountEqual(self.doc.relateddocument_set.values_list('relationship__slug', flat=True),
['refnorm', 'refinfo', 'refold', 'refunk', 'updates'],
'Test conditions set up incorrectly: wrong prior document relationships')
@ -380,7 +380,7 @@ class RebuildReferenceRelationsTests(TestCase):
self.assertEqual(
result,
{
'warnings': ['There were 1 references with no matching DocAlias'],
'warnings': ['There were 1 references with no matching Document'],
'unfound': ['draft-not-found'],
}
)
@ -391,7 +391,7 @@ class RebuildReferenceRelationsTests(TestCase):
(self.normative.canonical_name(), 'refnorm'),
(self.informative.canonical_name(), 'refinfo'),
(self.unknown.canonical_name(), 'refunk'),
(self.updated.docalias.first().name, 'updates'),
(self.updated.name, 'updates'),
]
)
@ -411,7 +411,7 @@ class RebuildReferenceRelationsTests(TestCase):
self.assertEqual(
result,
{
'warnings': ['There were 1 references with no matching DocAlias'],
'warnings': ['There were 1 references with no matching Document'],
'unfound': ['draft-not-found'],
}
)
@ -422,7 +422,7 @@ class RebuildReferenceRelationsTests(TestCase):
(self.normative.canonical_name(), 'refnorm'),
(self.informative.canonical_name(), 'refinfo'),
(self.unknown.canonical_name(), 'refunk'),
(self.updated.docalias.first().name, 'updates'),
(self.updated.name, 'updates'),
]
)
@ -443,7 +443,7 @@ class RebuildReferenceRelationsTests(TestCase):
self.assertEqual(
result,
{
'warnings': ['There were 1 references with no matching DocAlias'],
'warnings': ['There were 1 references with no matching Document'],
'unfound': ['draft-not-found'],
}
)
@ -454,6 +454,6 @@ class RebuildReferenceRelationsTests(TestCase):
(self.normative.canonical_name(), 'refnorm'),
(self.informative.canonical_name(), 'refinfo'),
(self.unknown.canonical_name(), 'refunk'),
(self.updated.docalias.first().name, 'updates'),
(self.updated.name, 'updates'),
]
)

View file

@ -31,7 +31,7 @@ from ietf.community.models import CommunityList
from ietf.community.utils import docs_tracked_by_community_list
from ietf.doc.models import Document, DocHistory, State, DocumentAuthor, DocHistoryAuthor
from ietf.doc.models import DocAlias, RelatedDocument, RelatedDocHistory, BallotType, DocReminder
from ietf.doc.models import RelatedDocument, RelatedDocHistory, BallotType, DocReminder
from ietf.doc.models import DocEvent, ConsensusDocEvent, BallotDocEvent, IRSGBallotDocEvent, NewRevisionDocEvent, StateDocEvent
from ietf.doc.models import TelechatDocEvent, DocumentActionHolder, EditedAuthorsDocEvent
from ietf.name.models import DocReminderTypeName, DocRelationshipName
@ -218,7 +218,7 @@ def needed_ballot_positions(doc, active_positions):
else:
related_set = RelatedDocHistory.objects.none()
for rel in related_set.filter(relationship__slug__in=['tops', 'tois', 'tohist', 'toinf', 'tobcp', 'toexp']):
if (rel.target.document.std_level_id in ['bcp','ps','ds','std']) or (rel.relationship_id in ['tops','tois','tobcp']):
if (rel.target.std_level_id in ['bcp','ps','ds','std']) or (rel.relationship_id in ['tops','tois','tobcp']):
needed = two_thirds_rule(recused=len(recuse))
break
else:
@ -771,22 +771,22 @@ def rebuild_reference_relations(doc, filenames):
errors = []
unfound = set()
for ( ref, refType ) in refs.items():
refdoc = DocAlias.objects.filter(name=ref)
refdoc = Document.objects.filter(name=ref)
if not refdoc and re.match(r"^draft-.*-\d{2}$", ref):
refdoc = DocAlias.objects.filter(name=ref[:-3])
refdoc = Document.objects.filter(name=ref[:-3])
count = refdoc.count()
# As of Dec 2021, DocAlias has a unique constraint on the name field, so count > 1 should not occur
if count == 0:
unfound.add( "%s" % ref )
continue
elif count > 1:
errors.append("Too many DocAlias objects found for %s"%ref)
errors.append("Too many Document objects found for %s"%ref)
else:
# Don't add references to ourself
if doc != refdoc[0].document:
if doc != refdoc[0]:
RelatedDocument.objects.get_or_create( source=doc, target=refdoc[ 0 ], relationship=DocRelationshipName.objects.get( slug='ref%s' % refType ) )
if unfound:
warnings.append('There were %d references with no matching DocAlias'%len(unfound))
warnings.append('There were %d references with no matching Document'%len(unfound))
ret = {}
if errors:
@ -821,26 +821,26 @@ def set_replaces_for_document(request, doc, new_replaces, by, email_subject, com
for d in old_replaces:
if d not in new_replaces:
other_addrs = gather_address_lists('doc_replacement_changed',doc=d.document)
other_addrs = gather_address_lists('doc_replacement_changed',doc=d)
to.update(other_addrs.to)
cc.update(other_addrs.cc)
RelatedDocument.objects.filter(source=doc, target=d, relationship=relationship).delete()
if not RelatedDocument.objects.filter(target=d, relationship=relationship):
s = 'active' if d.document.expires > timezone.now() else 'expired'
d.document.set_state(State.objects.get(type='draft', slug=s))
s = 'active' if d.expires > timezone.now() else 'expired'
d.set_state(State.objects.get(type='draft', slug=s))
for d in new_replaces:
if d not in old_replaces:
other_addrs = gather_address_lists('doc_replacement_changed',doc=d.document)
other_addrs = gather_address_lists('doc_replacement_changed',doc=d)
to.update(other_addrs.to)
cc.update(other_addrs.cc)
RelatedDocument.objects.create(source=doc, target=d, relationship=relationship)
d.document.set_state(State.objects.get(type='draft', slug='repl'))
d.set_state(State.objects.get(type='draft', slug='repl'))
if d.document.stream_id in ('irtf','ise','iab'):
repl_state = State.objects.get(type_id='draft-stream-%s'%d.document.stream_id, slug='repl')
d.document.set_state(repl_state)
events.append(StateDocEvent.objects.create(doc=d.document, rev=d.document.rev, by=by, type='changed_state', desc="Set stream state to Replaced",state_type=repl_state.type, state=repl_state))
if d.stream_id in ('irtf','ise','iab'):
repl_state = State.objects.get(type_id='draft-stream-%s'%d.stream_id, slug='repl')
d.set_state(repl_state)
events.append(StateDocEvent.objects.create(doc=d, rev=d.rev, by=by, type='changed_state', desc="Set stream state to Replaced",state_type=repl_state.type, state=repl_state))
# make sure there are no lingering suggestions duplicating new replacements
RelatedDocument.objects.filter(source=doc, target__in=new_replaces, relationship="possibly-replaces").delete()
@ -910,7 +910,7 @@ def extract_complete_replaces_ancestor_mapping_for_docs(names):
break
relations = ( RelatedDocument.objects.filter(source__name__in=front, relationship="replaces")
.select_related("target").values_list("source__name", "target__docs__name") )
.select_related("target").values_list("source__name", "target__name") )
if not relations:
break
@ -1141,7 +1141,7 @@ def generate_idnits2_rfc_status():
def generate_idnits2_rfcs_obsoleted():
obsdict = defaultdict(list)
for r in RelatedDocument.objects.filter(relationship_id='obs'):
obsdict[int(r.target.document.rfc_number)].append(int(r.source.rfc_number))
obsdict[int(r.target.rfc_number)].append(int(r.source.rfc_number)) # Aren't these already guaranteed to be ints?
for k in obsdict:
obsdict[k] = sorted(obsdict[k])
return render_to_string('doc/idnits2-rfcs-obsoleted.txt', context={'obsitems':sorted(obsdict.items())})

View file

@ -164,12 +164,11 @@ def fill_in_document_table_attributes(docs, have_telechat_date=False):
)
)
for rel in xed_by:
d = doc_dict[rel.target.document.id]
s = rel_rfc_aliases[rel.source_id]
d = doc_dict[rel.target.id]
if rel.relationship_id == "obs":
d.obsoleted_by_list.append(s)
d.obsoleted_by_list.append(rel.source)
elif rel.relationship_id == "updates":
d.updated_by_list.append(s)
d.updated_by_list.append(rel.source)
def augment_docs_with_related_docs_info(docs):
"""Augment all documents with related documents information.

View file

@ -958,7 +958,7 @@ def approve_downrefs(request, name):
for rel in doc.relateddocument_set.all()
if rel.is_downref()
and not rel.is_approved_downref()
and rel.target.document.type_id == "rfc"
and rel.target.type_id == "rfc"
]
downrefs_to_rfc_qs = RelatedDocument.objects.filter(pk__in=[r.pk for r in downrefs_to_rfc])
@ -974,12 +974,12 @@ def approve_downrefs(request, name):
c = DocEvent(type="downref_approved", doc=rel.source,
rev=rel.source.rev, by=login)
c.desc = "Downref to RFC %s approved by Last Call for %s-%s" % (
rel.target.document.rfc_number, rel.source, rel.source.rev)
rel.target.rfc_number, rel.source, rel.source.rev)
c.save()
c = DocEvent(type="downref_approved", doc=rel.target.document,
rev=rel.target.document.rev, by=login)
c = DocEvent(type="downref_approved", doc=rel.target,
rev=rel.target.rev, by=login)
c.desc = "Downref to RFC %s approved by Last Call for %s-%s" % (
rel.target.document.rfc_number, rel.source, rel.source.rev)
rel.target.rfc_number, rel.source, rel.source.rev)
c.save()
return HttpResponseRedirect(doc.get_absolute_url())

View file

@ -113,7 +113,7 @@ def send_conflict_review_ad_changed_email(request, review, event):
by = request.user.person,
event = event,
review = review,
reviewed_doc = review.relateddocument_set.get(relationship__slug='conflrev').target.document,
reviewed_doc = review.relateddocument_set.get(relationship__slug='conflrev').target,
review_url = settings.IDTRACKER_BASE_URL+review.get_absolute_url(),
)
)
@ -128,7 +128,7 @@ def send_conflict_review_started_email(request, review):
cc = addrs.cc,
by = request.user.person,
review = review,
reviewed_doc = review.relateddocument_set.get(relationship__slug='conflrev').target.document,
reviewed_doc = review.relateddocument_set.get(relationship__slug='conflrev').target,
review_url = settings.IDTRACKER_BASE_URL+review.get_absolute_url(),
)
)
@ -137,7 +137,7 @@ def send_conflict_review_started_email(request, review):
addrs = gather_address_lists('conflrev_requested_iana',doc=review).as_strings(compact=False)
email_iana(request,
review.relateddocument_set.get(relationship__slug='conflrev').target.document,
review.relateddocument_set.get(relationship__slug='conflrev').target,
addrs.to,
msg,
cc=addrs.cc)
@ -155,7 +155,7 @@ def send_conflict_eval_email(request,review):
send_mail_preformatted(request,msg,override=override)
addrs = gather_address_lists('ballot_issued_iana',doc=review).as_strings()
email_iana(request,
review.relateddocument_set.get(relationship__slug='conflrev').target.document,
review.relateddocument_set.get(relationship__slug='conflrev').target,
addrs.to,
msg,
addrs.cc)
@ -247,7 +247,7 @@ def submit(request, name):
{'form': form,
'next_rev': next_rev,
'review' : review,
'conflictdoc' : review.relateddocument_set.get(relationship__slug='conflrev').target.document,
'conflictdoc' : review.relateddocument_set.get(relationship__slug='conflrev').target,
})
@role_required("Area Director", "Secretariat")
@ -275,7 +275,7 @@ def edit_ad(request, name):
form = AdForm(initial=init)
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target.document
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target
titletext = 'the conflict review of %s-%s' % (conflictdoc.canonical_name(),conflictdoc.rev)
return render(request, 'doc/change_ad.html',
{'form': form,
@ -287,7 +287,7 @@ def edit_ad(request, name):
def default_approval_text(review):
current_text = review.text_or_error() # pyflakes:ignore
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target.document
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target
if conflictdoc.stream_id=='ise':
receiver = 'Independent Submissions Editor'
elif conflictdoc.stream_id=='irtf':
@ -365,7 +365,7 @@ def approve_conflict_review(request, name):
return render(request, 'doc/conflict_review/approve.html',
dict(
review = review,
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target.document,
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target,
form = form,
))
@ -416,7 +416,7 @@ def start_review_sanity_check(request, name):
raise Http404
# sanity check that there's not already a conflict review document for this document
if [ rel.source for alias in doc_to_review.docalias.all() for rel in alias.relateddocument_set.filter(relationship='conflrev') ]:
if [ rel.source for rel in doc_to_review.targets_related.filter(relationship='conflrev') ]:
raise Http404
return doc_to_review
@ -452,7 +452,7 @@ def build_conflict_review_document(login, doc_to_review, ad, notify, create_in_s
DocAlias.objects.create( name=review_name).docs.add( conflict_review )
conflict_review.relateddocument_set.create(target=DocAlias.objects.get(name=doc_to_review.name),relationship_id='conflrev')
conflict_review.relateddocument_set.create(target=doc_to_review, relationship_id='conflrev')
c = DocEvent(type="added_comment", doc=conflict_review, rev=conflict_review.rev, by=login)
c.desc = "IETF conflict review requested"

View file

@ -184,9 +184,8 @@ def interesting_doc_relations(doc):
that_doc_relationships = ('replaces', 'possibly_replaces', 'updates', 'obs', 'became_rfc')
# TODO: This returns the relationships in database order, which may not be the order we want to display them in.
interesting_relations_that = cls.objects.filter(target__docs=target, relationship__in=that_relationships).select_related('source')
interesting_relations_that_doc = cls.objects.filter(source=doc, relationship__in=that_doc_relationships).prefetch_related('target__docs')
interesting_relations_that = cls.objects.filter(target=target, relationship__in=that_relationships).select_related('source')
interesting_relations_that_doc = cls.objects.filter(source=doc, relationship__in=that_doc_relationships).prefetch_related('target')
return interesting_relations_that, interesting_relations_that_doc
@ -806,7 +805,7 @@ def document_main(request, name, rev=None, document_html=False):
if doc.get_state_slug() in ("iesgeval", ) and doc.active_ballot():
ballot_summary = needed_ballot_positions(doc, list(doc.active_ballot().active_balloter_positions().values()))
conflictdoc = doc.related_that_doc('conflrev')[0].document
conflictdoc = doc.related_that_doc('conflrev')[0]
return render(request, "doc/document_conflict_review.html",
dict(doc=doc,
@ -1127,8 +1126,8 @@ def get_diff_revisions(request, name, doc):
diff_documents = [doc]
diff_documents.extend(
Document.objects.filter(
docalias__relateddocument__source=doc,
docalias__relateddocument__relationship="replaces",
relateddocument__source=doc,
relateddocument__relationship="replaces",
)
)
@ -1722,7 +1721,7 @@ def telechat_date(request, name):
def doc_titletext(doc):
if doc.type.slug=='conflrev':
conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target.document
conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target
return 'the conflict review of %s' % conflictdoc.canonical_name()
return doc.canonical_name()

View file

@ -19,7 +19,7 @@ def downref_registry(request):
downref_doc_pairs = [ ]
downref_relations = RelatedDocument.objects.filter(relationship_id='downref-approval')
for rel in downref_relations:
downref_doc_pairs.append((rel.target.document, rel.source))
downref_doc_pairs.append((rel.target, rel.source))
return render(request, 'doc/downref.html', {
"doc_pairs": downref_doc_pairs,
@ -38,18 +38,18 @@ def downref_registry_add(request):
if form.is_valid():
drafts = form.cleaned_data['drafts']
rfc = form.cleaned_data['rfc']
for da in drafts:
RelatedDocument.objects.create(source=da.document,
for d in drafts:
RelatedDocument.objects.create(source=d,
target=rfc, relationship_id='downref-approval')
c = DocEvent(type="downref_approved", doc=da.document,
rev=da.document.rev, by=login)
c = DocEvent(type="downref_approved", doc=d,
rev=d.rev, by=login)
c.desc = "Downref to RFC %s approved by Last Call for %s-%s" % (
rfc.document.rfc_number, da.name, da.document.rev)
rfc.rfc_number, d.name, d.rev)
c.save()
c = DocEvent(type="downref_approved", doc=rfc.document,
rev=rfc.document.rev, by=login)
c = DocEvent(type="downref_approved", doc=rfc,
rev=rfc.rev, by=login)
c.desc = "Downref to RFC %s approved by Last Call for %s-%s" % (
rfc.document.rfc_number, da.name, da.document.rev)
rfc.rfc_number, d.name, d.rev)
c.save()
return HttpResponseRedirect(urlreverse('ietf.doc.views_downref.downref_registry'))

View file

@ -23,7 +23,7 @@ from django.utils import timezone
import debug # pyflakes:ignore
from ietf.doc.models import ( Document, DocAlias, RelatedDocument, State,
from ietf.doc.models import ( Document, RelatedDocument, State,
StateType, DocEvent, ConsensusDocEvent, TelechatDocEvent, WriteupDocEvent, StateDocEvent,
IanaExpertDocEvent, IESG_SUBSTATE_TAGS)
from ietf.doc.mails import ( email_pulled_from_rfc_queue, email_resurrect_requested,
@ -38,7 +38,7 @@ from ietf.doc.utils import ( add_state_change_event, can_adopt_draft, can_unadop
set_replaces_for_document, default_consensus, tags_suffix, can_edit_docextresources,
update_doc_extresources )
from ietf.doc.lastcall import request_last_call
from ietf.doc.fields import SearchableDocAliasesField
from ietf.doc.fields import SearchableDocumentsField
from ietf.doc.forms import ExtResourceForm
from ietf.group.models import Group, Role, GroupFeatures
from ietf.iesg.models import TelechatDate
@ -333,7 +333,7 @@ def change_stream(request, name):
))
class ReplacesForm(forms.Form):
replaces = SearchableDocAliasesField(required=False)
replaces = SearchableDocumentsField(required=False)
comment = forms.CharField(widget=forms.Textarea, required=False, strip=False)
def __init__(self, *args, **kwargs):
@ -343,9 +343,9 @@ class ReplacesForm(forms.Form):
def clean_replaces(self):
for d in self.cleaned_data['replaces']:
if d.document == self.doc:
if d == self.doc:
raise forms.ValidationError("An Internet-Draft can't replace itself")
if d.document.type_id == "draft" and d.document.get_state_slug() == "rfc":
if d.type_id == "draft" and d.get_state_slug() == "rfc":
raise forms.ValidationError("An Internet-Draft can't replace an RFC")
return self.cleaned_data['replaces']
@ -383,7 +383,7 @@ def replaces(request, name):
))
class SuggestedReplacesForm(forms.Form):
replaces = forms.ModelMultipleChoiceField(queryset=DocAlias.objects.all(),
replaces = forms.ModelMultipleChoiceField(queryset=Document.objects.all(),
label="Suggestions", required=False, widget=forms.CheckboxSelectMultiple,
help_text="Select only the documents that are replaced by this document")
comment = forms.CharField(label="Optional comment", widget=forms.Textarea, required=False, strip=False)
@ -673,7 +673,7 @@ def edit_info(request, name):
e.save()
events.append(e)
replaces = Document.objects.filter(docalias__relateddocument__source=doc, docalias__relateddocument__relationship="replaces")
replaces = Document.objects.filter(targets_related__source=doc, targets_related__relationship="replaces")
if replaces:
# this should perhaps be somewhere else, e.g. the
# place where the replace relationship is established?

View file

@ -98,8 +98,8 @@ def change_state(request, name, option=None):
relationship__slug__in=STATUSCHANGE_RELATIONS
)
related_doc_info = [
dict(title=rel_doc.target.document.title,
canonical_name=rel_doc.target.document.canonical_name(),
dict(title=rel_doc.target.title,
canonical_name=rel_doc.target.canonical_name(),
newstatus=newstatus(rel_doc))
for rel_doc in related_docs
]
@ -309,7 +309,7 @@ def default_approval_text(status_change,relateddoc):
current_text = status_change.text_or_error() # pyflakes:ignore
if relateddoc.target.document.std_level_id in ('std','ps','ds','bcp',):
if relateddoc.target.std_level_id in ('std','ps','ds','bcp',):
action = "Protocol Action"
else:
action = "Document Action"
@ -320,7 +320,7 @@ def default_approval_text(status_change,relateddoc):
dict(status_change=status_change,
status_change_url = settings.IDTRACKER_BASE_URL+status_change.get_absolute_url(),
relateddoc= relateddoc,
relateddoc_url = settings.IDTRACKER_BASE_URL+relateddoc.target.document.get_absolute_url(),
relateddoc_url = settings.IDTRACKER_BASE_URL+relateddoc.target.get_absolute_url(),
approved_text = current_text,
action=action,
newstatus=newstatus(relateddoc),
@ -388,7 +388,7 @@ def approve(request, name):
for rel in status_change.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS):
# Add a document event to each target
c = DocEvent(type="added_comment", doc=rel.target.document, rev=rel.target.document.rev, by=login)
c = DocEvent(type="added_comment", doc=rel.target, rev=rel.target.rev, by=login)
c.desc = "New status of %s approved by the IESG\n%s%s" % (newstatus(rel), settings.IDTRACKER_BASE_URL,reverse('ietf.doc.views_doc.document_main', kwargs={'name': status_change.name}))
c.save()
@ -399,7 +399,7 @@ def approve(request, name):
init = []
for rel in status_change.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS):
init.append({"announcement_text" : escape(default_approval_text(status_change,rel)),
"label": "Announcement text for %s to %s"%(rel.target.document.canonical_name(),newstatus(rel)),
"label": "Announcement text for %s to %s"%(rel.target.canonical_name(),newstatus(rel)),
})
formset = AnnouncementFormSet(initial=init)
for form in formset.forms:
@ -439,7 +439,7 @@ def clean_helper(form, formtype):
if not re.match(r'(?i)rfc\d{1,4}',key):
errors.append(key+" is not a valid RFC - please use the form RFCn\n")
elif not DocAlias.objects.filter(name=key):
elif not Document.objects.filter(name=key):
errors.append(key+" does not exist\n")
if new_relations[key] not in STATUSCHANGE_RELATIONS:
@ -564,10 +564,9 @@ def start_rfc_status_change(request, name=None):
DocAlias.objects.create( name= 'status-change-'+form.cleaned_data['document_name']).docs.add(status_change)
for key in form.cleaned_data['relations']:
status_change.relateddocument_set.create(target=DocAlias.objects.get(name=key),
status_change.relateddocument_set.create(target=Document.objects.get(name=key),
relationship_id=form.cleaned_data['relations'][key])
tc_date = form.cleaned_data['telechat_date']
if tc_date:
update_telechat(request, status_change, login, tc_date)
@ -605,11 +604,11 @@ def edit_relations(request, name):
old_relations={}
for rel in status_change.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS):
old_relations[rel.target.document.canonical_name()]=rel.relationship.slug
old_relations[rel.target.canonical_name()]=rel.relationship.slug
new_relations=form.cleaned_data['relations']
status_change.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS).delete()
for key in new_relations:
status_change.relateddocument_set.create(target=DocAlias.objects.get(name=key),
status_change.relateddocument_set.create(target=Document.objects.get(name=key),
relationship_id=new_relations[key])
c = DocEvent(type="added_comment", doc=status_change, rev=status_change.rev, by=login)
c.desc = "Affected RFC list changed.\nOLD:"
@ -626,7 +625,7 @@ def edit_relations(request, name):
else:
relations={}
for rel in status_change.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS):
relations[rel.target.document.canonical_name()]=rel.relationship.slug
relations[rel.target.canonical_name()]=rel.relationship.slug
init = { "relations":relations,
}
form = EditStatusChangeForm(initial=init)
@ -653,8 +652,8 @@ def generate_last_call_text(request, doc):
settings=settings,
requester=requester,
expiration_date=expiration_date.strftime("%Y-%m-%d"),
changes=['%s from %s to %s\n (%s)'%(rel.target.name.upper(),rel.target.document.std_level.name,newstatus(rel),rel.target.document.title) for rel in doc.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS)],
urls=[rel.target.document.get_absolute_url() for rel in doc.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS)],
changes=['%s from %s to %s\n (%s)'%(rel.target.name.upper(),rel.target.std_level.name,newstatus(rel),rel.target.title) for rel in doc.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS)],
urls=[rel.target.get_absolute_url() for rel in doc.relateddocument_set.filter(relationship__slug__in=STATUSCHANGE_RELATIONS)],
cc=cc
)
)

View file

@ -69,7 +69,7 @@ class GroupStatsTests(TestCase):
a = WgDraftFactory()
b = WgDraftFactory()
RelatedDocument.objects.create(
source=a, target=b.docalias.first(), relationship_id="refnorm"
source=a, target=b, relationship_id="refnorm"
)
def test_group_stats(self):
@ -95,7 +95,7 @@ class GroupDocDependencyTests(TestCase):
a = WgDraftFactory()
b = WgDraftFactory()
RelatedDocument.objects.create(
source=a, target=b.docalias.first(), relationship_id="refnorm"
source=a, target=b, relationship_id="refnorm"
)
def test_group_document_dependencies(self):

View file

@ -756,7 +756,7 @@ def dependencies(request, acronym, group_type=None):
relationship__slug__startswith="ref",
)
both_rfcs = Q(source__states__slug="rfc", target__docs__states__slug="rfc")
both_rfcs = Q(source__states__slug="rfc", target__states__slug="rfc")
inactive = Q(source__states__slug__in=["expired", "repl"])
attractor = Q(target__name__in=["rfc5000", "rfc5741"])
removed = Q(source__states__slug__in=["auth-rm", "ietf-rm"])
@ -770,19 +770,19 @@ def dependencies(request, acronym, group_type=None):
links = set()
for x in relations:
target_state = x.target.document.get_state_slug("draft")
target_state = x.target.get_state_slug("draft")
if target_state != "rfc" or x.is_downref():
links.add(x)
replacements = RelatedDocument.objects.filter(
relationship__slug="replaces",
target__docs__in=[x.target.document for x in links],
target__in=[x.target for x in links],
)
for x in replacements:
links.add(x)
nodes = set([x.source for x in links]).union([x.target.document for x in links])
nodes = set([x.source for x in links]).union([x.target for x in links])
graph = {
"nodes": [
{
@ -805,7 +805,7 @@ def dependencies(request, acronym, group_type=None):
"links": [
{
"source": x.source.canonical_name(),
"target": x.target.document.canonical_name(),
"target": x.target.canonical_name(),
"rel": "downref" if x.is_downref() else x.relationship.slug,
}
for x in links

View file

@ -34,7 +34,7 @@ def all_id_txt():
rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc",
docs__states=State.objects.get(type="draft", slug="rfc")).values_list("docs__name", "name"))
replacements = dict(RelatedDocument.objects.filter(target__docs__states=State.objects.get(type="draft", slug="repl"),
replacements = dict(RelatedDocument.objects.filter(target__states=State.objects.get(type="draft", slug="repl"),
relationship="replaces").values_list("target__name", "source__name"))
@ -115,7 +115,7 @@ def all_id2_txt():
rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc",
docs__states=State.objects.get(type="draft", slug="rfc")).values_list("docs__name", "name"))
replacements = dict(RelatedDocument.objects.filter(target__docs__states=State.objects.get(type="draft", slug="repl"),
replacements = dict(RelatedDocument.objects.filter(target__states=State.objects.get(type="draft", slug="repl"),
relationship="replaces").values_list("target__name", "source__name"))
revision_time = dict(DocEvent.objects.filter(type="new_revision", doc__name__startswith="draft-").order_by('time').values_list("doc__name", "time"))

View file

@ -52,8 +52,13 @@ class IndexTests(TestCase):
RelatedDocument.objects.create(
relationship=DocRelationshipName.objects.get(slug="replaces"),
source=Document.objects.create(type_id="draft", rev="00", name="draft-test-replacement"),
target=draft.docalias.get(name__startswith="draft"))
source=Document.objects.create(
type_id="draft",
rev="00",
name="draft-test-replacement"
),
target=draft
)
txt = all_id_txt()
self.assertTrue(draft.name + "-" + draft.rev in txt)
@ -111,8 +116,12 @@ class IndexTests(TestCase):
draft.set_state(State.objects.get(type="draft", slug="repl"))
RelatedDocument.objects.create(
relationship=DocRelationshipName.objects.get(slug="replaces"),
source=Document.objects.create(type_id="draft", rev="00", name="draft-test-replacement"),
target=draft.docalias.get(name__startswith="draft"))
source=Document.objects.create(
type_id="draft",
rev="00",
name="draft-test-replacement"
),
target=draft)
t = get_fields(all_id2_txt())
self.assertEqual(t[5], "draft-test-replacement")

View file

@ -66,7 +66,7 @@ def get_doc_section(doc):
elif doc.type_id == 'statchg':
protocol_action = False
for relation in doc.relateddocument_set.filter(relationship__slug__in=('tops','tois','tohist','toinf','tobcp','toexp')):
if relation.relationship_id in ('tops','tois') or relation.target.document.std_level_id in ('std','ds','ps'):
if relation.relationship_id in ('tops','tois') or relation.target.std_level_id in ('std','ds','ps'):
protocol_action = True
if protocol_action:
s = "2.3"
@ -186,7 +186,7 @@ def fill_in_agenda_docs(date, sections, docs=None):
doc.review_assignments = review_assignments_for_docs.get(doc.name, [])
elif doc.type_id == "conflrev":
doc.conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target.document
doc.conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target
elif doc.type_id == "charter":
pass
@ -219,4 +219,4 @@ def agenda_data(date=None):
fill_in_agenda_docs(date, sections)
fill_in_agenda_management_issues(date, sections)
return { 'date': date.isoformat(), 'sections': sections }
return { 'date': date.isoformat(), 'sections': sections }

View file

@ -17,7 +17,7 @@ from django.utils.html import escape
import debug # pyflakes:ignore
from ietf.doc.models import DocEvent, BallotPositionDocEvent, TelechatDocEvent
from ietf.doc.models import Document, DocAlias, State, RelatedDocument
from ietf.doc.models import Document, State, RelatedDocument
from ietf.doc.factories import WgDraftFactory, IndividualDraftFactory, ConflictReviewFactory, BaseDocumentFactory, CharterFactory, WgRfcFactory, IndividualRfcFactory
from ietf.doc.utils import create_ballot_if_not_open
from ietf.group.factories import RoleFactory, GroupFactory
@ -108,7 +108,7 @@ class IESGAgendaTests(TestCase):
mars = GroupFactory(acronym='mars',parent=Group.objects.get(acronym='farfut'))
wgdraft = WgDraftFactory(name='draft-ietf-mars-test', group=mars, intended_std_level_id='ps')
rfc = IndividualRfcFactory.create(stream_id='irtf', rfc_number=6666, std_level_id='inf', )
wgdraft.relateddocument_set.create(target=rfc.docalias.get(name='rfc6666'), relationship_id='refnorm')
wgdraft.relateddocument_set.create(target=rfc, relationship_id='refnorm')
ise_draft = IndividualDraftFactory(name='draft-imaginary-independent-submission')
ise_draft.stream = StreamName.objects.get(slug="ise")
ise_draft.save_with_history([DocEvent(doc=ise_draft, rev=ise_draft.rev, type="changed_stream", by=Person.objects.get(user__username="secretary"), desc="Test")])
@ -238,7 +238,7 @@ class IESGAgendaTests(TestCase):
relation = RelatedDocument.objects.create(
source=statchg,
target=DocAlias.objects.filter(name__startswith='rfc', docs__std_level="ps")[0],
target=Document.objects.filter(type_id="rfc", std_level="ps").first(),
relationship_id="tohist")
statchg.group = Group.objects.get(acronym="mars")
@ -256,7 +256,7 @@ class IESGAgendaTests(TestCase):
self.assertTrue(statchg in agenda_data(date_str)["sections"]["2.3.3"]["docs"])
# 3.3 document status changes
relation.target = DocAlias.objects.filter(name__startswith='rfc', docs__std_level="inf")[0]
relation.target = Document.objects.filter(type_id="rfc", std_level="inf").first()
relation.save()
statchg.group = Group.objects.get(acronym="mars")

View file

@ -32,10 +32,10 @@ def telechat_page_count(date=None, docs=None):
pages_for_action += d.pages or 0
elif d.type_id == 'statchg':
for rel in d.related_that_doc(STATUSCHANGE_RELATIONS):
pages_for_action += rel.document.pages or 0
pages_for_action += rel.pages or 0
elif d.type_id == 'conflrev':
for rel in d.related_that_doc('conflrev'):
pages_for_action += rel.document.pages or 0
pages_for_action += rel.pages or 0
else:
pass
@ -43,10 +43,10 @@ def telechat_page_count(date=None, docs=None):
for d in for_approval-set(drafts):
if d.type_id == 'statchg':
for rel in d.related_that_doc(STATUSCHANGE_RELATIONS):
related_pages += rel.document.pages or 0
related_pages += rel.pages or 0
elif d.type_id == 'conflrev':
for rel in d.related_that_doc('conflrev'):
related_pages += rel.document.pages or 0
related_pages += rel.pages or 0
else:
# There's really nothing to rely on to give a reading load estimate for charters
pass

View file

@ -172,7 +172,7 @@ def agenda_json(request, date=None):
elif doc.type_id == 'conflrev':
docinfo['rev'] = doc.rev
td = doc.relateddocument_set.get(relationship__slug='conflrev').target.document
td = doc.relateddocument_set.get(relationship__slug='conflrev').target
docinfo['target-docname'] = td.canonical_name()
docinfo['target-title'] = td.title
docinfo['target-rev'] = td.rev

View file

@ -94,7 +94,7 @@ admin.site.register(IprDocRel, IprDocRelAdmin)
class RelatedIprAdmin(admin.ModelAdmin):
list_display = ['source', 'target', 'relationship', ]
search_fields = ['source__name', 'target__name', 'target__docs__name', ]
search_fields = ['source__name', 'target__name', ]
raw_id_fields = ['source', 'target', ]
admin.site.register(RelatedIpr, RelatedIprAdmin)

View file

@ -41,24 +41,17 @@ def iprs_from_docs(aliases,**kwargs):
iprdocrels += document.ipr(**kwargs)
return list(set([i.disclosure for i in iprdocrels]))
def related_docs(alias, relationship=('replaces', 'obs')):
def related_docs(doc, relationship=('replaces', 'obs')):
"""Returns list of related documents"""
results = []
for doc in alias.docs.all():
results += list(doc.docalias.all())
rels = []
for doc in alias.docs.all():
rels += list(doc.all_relations_that_doc(relationship))
results = [doc]
rels = list(doc.document.all_relations_that_doc(relationship))
for rel in rels:
rel_aliases = list(rel.target.document.docalias.all())
for x in rel_aliases:
x.related = rel
x.relation = rel.relationship.revname
results += rel_aliases
rel.target.related = rel
rel.target.relation = rel.relationship.revname
results += [x.target for x in rels]
return list(set(results))

View file

@ -96,35 +96,35 @@ class Recipient(models.Model):
addrs = []
if 'doc' in kwargs:
for reldoc in kwargs['doc'].related_that_doc(('conflrev','tohist','tois','tops')):
addrs.extend(Recipient.objects.get(slug='doc_authors').gather(**{'doc':reldoc.document}))
addrs.extend(Recipient.objects.get(slug='doc_authors').gather(**{'doc':reldoc}))
return addrs
def gather_doc_affecteddoc_group_chairs(self, **kwargs):
addrs = []
if 'doc' in kwargs:
for reldoc in kwargs['doc'].related_that_doc(('conflrev','tohist','tois','tops')):
addrs.extend(Recipient.objects.get(slug='doc_group_chairs').gather(**{'doc':reldoc.document}))
addrs.extend(Recipient.objects.get(slug='doc_group_chairs').gather(**{'doc':reldoc}))
return addrs
def gather_doc_affecteddoc_notify(self, **kwargs):
addrs = []
if 'doc' in kwargs:
for reldoc in kwargs['doc'].related_that_doc(('conflrev','tohist','tois','tops')):
addrs.extend(Recipient.objects.get(slug='doc_notify').gather(**{'doc':reldoc.document}))
addrs.extend(Recipient.objects.get(slug='doc_notify').gather(**{'doc':reldoc}))
return addrs
def gather_conflict_review_stream_manager(self, **kwargs):
addrs = []
if 'doc' in kwargs:
for reldoc in kwargs['doc'].related_that_doc(('conflrev',)):
addrs.extend(Recipient.objects.get(slug='doc_stream_manager').gather(**{'doc':reldoc.document}))
addrs.extend(Recipient.objects.get(slug='doc_stream_manager').gather(**{'doc':reldoc}))
return addrs
def gather_conflict_review_steering_group(self,**kwargs):
addrs = []
if 'doc' in kwargs:
for reldoc in kwargs['doc'].related_that_doc(('conflrev',)):
if reldoc.document.stream_id=='irtf':
if reldoc.stream_id=='irtf':
addrs.append('"Internet Research Steering Group" <irsg@irtf.org>')
return addrs

View file

@ -68,8 +68,7 @@ class SecrTelechatTestCase(TestCase):
ad = Person.objects.get(user__username="ad")
draft = WgDraftFactory(ad=ad, intended_std_level_id='ps', states=[('draft-iesg','pub-req'),])
rfc = IndividualRfcFactory.create(stream_id='irtf', rfc_number=6666, std_level_id='inf')
draft.relateddocument_set.create(target=rfc.docalias.get(name='rfc6666'),
relationship_id='refnorm')
draft.relateddocument_set.create(target=rfc, relationship_id='refnorm')
create_ballot_if_not_open(None, draft, ad, 'approve')
d = get_next_telechat_date()
date = d.strftime('%Y-%m-%d')

View file

@ -313,7 +313,7 @@ def doc_detail(request, date, name):
# if this is a conflict review document add referenced document
if doc.type_id == 'conflrev':
conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target.document
conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target
else:
conflictdoc = None

View file

@ -85,13 +85,13 @@
{% if downrefs %}
<h2 id="downrefs">Downward References</h2>
{% for ref in downrefs %}
<p>Add {{ref.target.document.canonical_name}}
({{ref.target.document.std_level}} - {{ref.target.document.stream.desc}})
<p>Add {{ref.target.canonical_name}}
({{ref.target.std_level}} - {{ref.target.stream.desc}})
to downref registry.<br>
{% if not ref.target.document.std_level %}
{% if not ref.target.std_level %}
+++ Warning: The standards level has not been set yet!!!<br>
{% endif %}
{% if not ref.target.document.stream %}
{% if not ref.target.stream %}
+++ Warning: document stream has not been set yet!!!<br>
{% endif %}
{% endfor %}</p>

View file

@ -82,7 +82,7 @@ class StatisticsTests(TestCase):
DocAlias.objects.create(name=referencing_draft.name).docs.add(referencing_draft)
RelatedDocument.objects.create(
source=referencing_draft,
target=draft.docalias.first(),
target=draft,
relationship=DocRelationshipName.objects.get(slug="refinfo")
)
NewRevisionDocEvent.objects.create(

View file

@ -563,11 +563,11 @@ def document_stats(request, stats_type=None):
bins = defaultdict(set)
cite_relationships = list(DocRelationshipName.objects.filter(slug__in=['refnorm', 'refinfo', 'refunk', 'refold']))
person_filters &= Q(documentauthor__document__docalias__relateddocument__relationship__in=cite_relationships)
person_filters &= Q(documentauthor__document__relateddocument__relationship__in=cite_relationships)
person_qs = Person.objects.filter(person_filters)
for name, citations in person_qs.values_list("name").annotate(Count("documentauthor__document__docalias__relateddocument")):
for name, citations in person_qs.values_list("name").annotate(Count("documentauthor__document__relateddocument")):
bins[citations or 0].add(name)
total_persons = count_bins(bins)
@ -587,11 +587,11 @@ def document_stats(request, stats_type=None):
bins = defaultdict(set)
cite_relationships = list(DocRelationshipName.objects.filter(slug__in=['refnorm', 'refinfo', 'refunk', 'refold']))
person_filters &= Q(documentauthor__document__docalias__relateddocument__relationship__in=cite_relationships)
person_filters &= Q(documentauthor__document__relateddocument__relationship__in=cite_relationships)
person_qs = Person.objects.filter(person_filters)
values = person_qs.values_list("name", "documentauthor__document").annotate(Count("documentauthor__document__docalias__relateddocument"))
values = person_qs.values_list("name", "documentauthor__document").annotate(Count("documentauthor__document__relateddocument"))
for name, ts in itertools.groupby(values.order_by("name"), key=lambda t: t[0]):
h_index = compute_hirsch_index([citations for _, document, citations in ts])
bins[h_index or 0].add(name)

View file

@ -28,8 +28,7 @@ import debug # pyflakes:ignore
from ietf.doc.models import Document
from ietf.group.models import Group
from ietf.ietfauth.utils import has_role
from ietf.doc.fields import SearchableDocAliasesField
from ietf.doc.models import DocAlias
from ietf.doc.fields import SearchableDocumentsField
from ietf.ipr.mail import utc_from_string
from ietf.meeting.models import Meeting
from ietf.message.models import Message
@ -684,9 +683,9 @@ class SubmissionAutoUploadForm(SubmissionBaseUploadForm):
if self.cleaned_data['replaces']:
names_replaced = [s.strip() for s in self.cleaned_data['replaces'].split(',')]
self.cleaned_data['replaces'] = ','.join(names_replaced)
aliases_replaced = DocAlias.objects.filter(name__in=names_replaced)
if len(names_replaced) != len(aliases_replaced):
known_names = aliases_replaced.values_list('name', flat=True)
documents_replaced = Document.objects.filter(name__in=names_replaced)
if len(names_replaced) != len(documents_replaced):
known_names = documents_replaced.values_list('name', flat=True)
unknown_names = [n for n in names_replaced if n not in known_names]
self.add_error(
'replaces',
@ -694,27 +693,27 @@ class SubmissionAutoUploadForm(SubmissionBaseUploadForm):
'Unknown Internet-Draft name(s): ' + ', '.join(unknown_names)
),
)
for alias in aliases_replaced:
if alias.document.name == self.filename:
for doc in documents_replaced:
if doc.name == self.filename:
self.add_error(
'replaces',
forms.ValidationError("An Internet-Draft cannot replace itself"),
)
elif alias.document.type_id != "draft":
elif doc.type_id != "draft":
self.add_error(
'replaces',
forms.ValidationError("An Internet-Draft can only replace another Internet-Draft"),
)
elif alias.document.get_state_slug() == "rfc":
elif doc.get_state_slug() == "rfc":
self.add_error(
'replaces',
forms.ValidationError("An Internet-Draft cannot replace another Internet-Draft that has become an RFC"),
)
elif alias.document.get_state_slug('draft-iesg') in ('approved', 'ann', 'rfcqueue'):
elif doc.get_state_slug('draft-iesg') in ('approved', 'ann', 'rfcqueue'):
self.add_error(
'replaces',
forms.ValidationError(
alias.name + " is approved by the IESG and cannot be replaced"
doc.name + " is approved by the IESG and cannot be replaced"
),
)
return cleaned_data
@ -755,22 +754,20 @@ class SubmitterForm(NameEmailForm):
return line
class ReplacesForm(forms.Form):
replaces = SearchableDocAliasesField(required=False, help_text="Any Internet-Drafts that this document replaces (approval required for replacing an Internet-Draft you are not the author of)")
replaces = SearchableDocumentsField(required=False, help_text="Any Internet-Drafts that this document replaces (approval required for replacing an Internet-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:
for doc in self.cleaned_data['replaces']:
if doc.name == self.name:
raise forms.ValidationError("An Internet-Draft cannot replace itself.")
if alias.document.type_id != "draft":
if doc.type_id != "draft":
raise forms.ValidationError("An Internet-Draft can only replace another Internet-Draft")
if alias.document.get_state_slug() == "rfc":
raise forms.ValidationError("An Internet-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")
if doc.get_state_slug('draft-iesg') in ('approved','ann','rfcqueue'):
raise forms.ValidationError(doc.name+" is approved by the IESG and cannot be replaced")
return self.cleaned_data['replaces']
class EditSubmissionForm(forms.ModelForm):

View file

@ -302,7 +302,7 @@ class SubmitTests(BaseSubmitTestCase):
submission = Submission.objects.get(name=name)
self.assertEqual(submission.submitter, email.utils.formataddr((submitter_name, submitter_email)))
self.assertEqual([] if submission.replaces == "" else submission.replaces.split(','),
[ d.name for d in DocAlias.objects.filter(pk__in=replaces) ])
[ d.name for d in Document.objects.filter(pk__in=replaces) ])
self.assertCountEqual(
[str(r) for r in submission.external_resources.all()],
[str(r) for r in extresources] if extresources else [],
@ -369,9 +369,8 @@ class SubmitTests(BaseSubmitTestCase):
# supply submitter info, then draft should be in and ready for approval
mailbox_before = len(outbox)
replaced_alias = draft.docalias.first()
r = self.supply_extra_metadata(name, status_url, author.ascii, author.email().address.lower(),
replaces=[str(replaced_alias.pk), str(sug_replaced_alias.pk)])
replaces=[str(draft.pk), str(sug_replaced_draft.pk)])
self.assertEqual(r.status_code, 302)
status_url = r["Location"]
@ -419,7 +418,7 @@ class SubmitTests(BaseSubmitTestCase):
self.assertEqual(authors[0].person, author)
self.assertEqual(set(draft.formal_languages.all()), set(FormalLanguageName.objects.filter(slug="json")))
self.assertEqual(draft.relations_that_doc("replaces").count(), 1)
self.assertTrue(draft.relations_that_doc("replaces").first().target, replaced_alias)
self.assertTrue(draft.relations_that_doc("replaces").first().target, draft)
self.assertEqual(draft.relations_that_doc("possibly-replaces").count(), 1)
self.assertTrue(draft.relations_that_doc("possibly-replaces").first().target, sug_replaced_alias)
self.assertEqual(len(outbox), mailbox_before + 5)
@ -1142,7 +1141,7 @@ class SubmitTests(BaseSubmitTestCase):
self.verify_bibxml_ids_creation(draft)
def test_submit_update_individual(self):
IndividualDraftFactory(name='draft-ietf-random-thing', states=[('draft','rfc')], other_aliases=['rfc9999',], pages=5)
IndividualDraftFactory(name='draft-ietf-random-thing', states=[('draft','active'),('draft-iesg','approved')], pages=5)
ad=Person.objects.get(user__username='ad')
# Group of None here does not reflect real individual submissions
draft = IndividualDraftFactory(group=None, ad = ad, authors=[ad,], notify='aliens@example.mars', pages=5)
@ -1152,23 +1151,14 @@ class SubmitTests(BaseSubmitTestCase):
status_url, author = self.do_submission(name,rev)
mailbox_before = len(outbox)
replaced_alias = draft.docalias.first()
r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=[str(replaced_alias.pk)])
r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=[str(draft.pk)])
self.assertEqual(r.status_code, 200)
self.assertContains(r, 'cannot replace itself')
self._assert_extresources_in_table(r, [])
self._assert_extresources_form(r, [])
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.assertContains(r, 'cannot replace an RFC')
self._assert_extresources_in_table(r, [])
self._assert_extresources_form(r, [])
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)])
replaced = Document.objects.get(name='draft-ietf-random-thing')
r = self.supply_extra_metadata(name, status_url, "Submitter Name", "author@example.com", replaces=[str(replaced.pk)])
self.assertEqual(r.status_code, 200)
self.assertContains(r, 'approved by the IESG and cannot')
self._assert_extresources_in_table(r, [])
@ -1262,7 +1252,7 @@ class SubmitTests(BaseSubmitTestCase):
status_url,
"Submitter Name",
"submitter@example.com",
replaces=[str(replaced_draft.docalias.first().pk)],
replaces=[str(replaced_draft.pk)],
)
submission = Submission.objects.get(name=name, rev=rev)
@ -1412,7 +1402,7 @@ class SubmitTests(BaseSubmitTestCase):
"edit-pages": "123",
"submitter-name": "Some Random Test Person",
"submitter-email": "random@example.com",
"replaces": [str(draft.docalias.first().pk)],
"replaces": [str(draft.pk)],
"edit-note": "no comments",
"authors-0-name": "Person 1",
"authors-0-email": "person1@example.com",
@ -1431,7 +1421,7 @@ class SubmitTests(BaseSubmitTestCase):
self.assertEqual(submission.pages, 123)
self.assertEqual(submission.note, "no comments")
self.assertEqual(submission.submitter, "Some Random Test Person <random@example.com>")
self.assertEqual(submission.replaces, draft.docalias.first().name)
self.assertEqual(submission.replaces, draft.name)
self.assertEqual(submission.state_id, "manual")
authors = submission.authors
@ -3100,7 +3090,7 @@ class SubmissionUploadFormTests(BaseSubmitTestCase):
# can't replace RFC
rfc = WgRfcFactory()
draft = WgDraftFactory(states=[("draft", "rfc")])
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc.docalias.first())
draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc)
form = SubmissionAutoUploadForm(
request_factory.get('/some/url'),
data={'user': auth.user.username, 'replaces': draft.name},

View file

@ -504,7 +504,7 @@ def update_replaces_from_submission(request, submission, draft):
if request.user.is_authenticated:
is_chair_of = list(Group.objects.filter(role__person__user=request.user, role__name="chair"))
replaces = DocAlias.objects.filter(name__in=submission.replaces.split(",")).prefetch_related("docs", "docs__group")
replaces = Document.objects.filter(name__in=submission.replaces.split(",")).prefetch_related("group")
existing_replaces = list(draft.related_that_doc("replaces"))
existing_suggested = set(draft.related_that_doc("possibly-replaces"))
@ -516,14 +516,12 @@ def update_replaces_from_submission(request, submission, draft):
if r in existing_replaces:
continue
rdoc = r.document
if rdoc == draft:
if r == draft:
continue
if (is_secretariat
or (draft.group in is_chair_of and (rdoc.group.type_id == "individ" or rdoc.group in is_chair_of))
or (submitter_email and rdoc.documentauthor_set.filter(email__address__iexact=submitter_email).exists())):
or (draft.group in is_chair_of and (r.group.type_id == "individ" or r.group in is_chair_of))
or (submitter_email and r.documentauthor_set.filter(email__address__iexact=submitter_email).exists())):
approved.append(r)
else:
if r not in existing_suggested:

View file

@ -488,12 +488,15 @@ def update_docs_from_rfc_index(index_data, errata_data, skip_older_than_date=Non
def parse_relation_list(l):
res = []
for x in l:
if x[:3] in ("NIC", "IEN", "STD", "RTR"):
# try translating this to RFCs that we can handle
# sensibly; otherwise we'll have to ignore them
l = DocAlias.objects.filter(name__startswith="rfc", docs__docalias__name=x.lower())
else:
l = DocAlias.objects.filter(name=x.lower())
# This lookup wasn't finding anything but maybe some STD and we know
# if the STD had more than one RFC the wrong thing happens
#
#if x[:3] in ("NIC", "IEN", "STD", "RTR"):
# # try translating this to RFCs that we can handle
# # sensibly; otherwise we'll have to ignore them
# l = DocAlias.objects.filter(name__startswith="rfc", docs__docalias__name=x.lower())
#else:
l = Document.objects.filter(name=x.lower())
for a in l:
if a not in res:

View file

@ -14,7 +14,7 @@ from django.utils import timezone
import debug # pyflakes:ignore
from ietf.doc.factories import WgDraftFactory
from ietf.doc.factories import WgDraftFactory, RfcFactory
from ietf.doc.models import Document, DocAlias, DocEvent, DeletedEvent, DocTagName, RelatedDocument, State, StateDocEvent
from ietf.doc.utils import add_state_change_event
from ietf.group.factories import GroupFactory
@ -235,9 +235,7 @@ class RFCSyncTests(TestCase):
# too, but for testing purposes ...
doc.action_holders.add(doc.ad) # not normally set, but add to be sure it's cleared
updated_doc = Document.objects.create(name="draft-ietf-something")
DocAlias.objects.create(name=updated_doc.name).docs.add(updated_doc)
DocAlias.objects.create(name="rfc123").docs.add(updated_doc)
RfcFactory(rfc_number=123)
today = date_today()
@ -360,7 +358,7 @@ class RFCSyncTests(TestCase):
self.assertTrue(DocAlias.objects.filter(name="bcp1", docs=doc))
self.assertTrue(DocAlias.objects.filter(name="fyi1", docs=doc))
self.assertTrue(DocAlias.objects.filter(name="std1", docs=doc))
self.assertTrue(RelatedDocument.objects.filter(source=doc, target__name="rfc123", relationship="updates"))
self.assertTrue(RelatedDocument.objects.filter(source=doc, target__name="rfc123", relationship="updates").exists())
self.assertEqual(doc.title, "A Testing RFC")
self.assertEqual(doc.abstract, "This is some interesting text.")
self.assertEqual(doc.get_state_slug(), "rfc")
@ -602,4 +600,4 @@ class RFCEditorUndoTests(TestCase):
e = DeletedEvent.objects.all().order_by("-time", "-id")[0]
e.content_type.model_class().objects.create(**json.loads(e.json))
self.assertTrue(StateDocEvent.objects.filter(desc="First", doc=draft))
self.assertTrue(StateDocEvent.objects.filter(desc="First", doc=draft))

View file

@ -35,7 +35,7 @@
<a href="{% url 'ietf.doc.views_doc.document_main' name=name %}">{{ name|prettystdname }}</a>
</td>
<td>
<b>{{ ref.target.document.title }}</b>
<b>{{ ref.target.title }}</b>
<br>
<a class="btn btn-primary btn-sm"
href="{% url 'ietf.doc.views_doc.document_references' name %}"
@ -51,12 +51,12 @@
</a>
</td>
<td>
{% if ref.target.document.type_id == "rfc" %}
{% with ref.target.document.std_level as lvl %}
{% if ref.target.type_id == "rfc" %}
{% with ref.target.std_level as lvl %}
{% if lvl %}{{ lvl }}{% endif %}
{% endwith %}
{% else %}
{% with ref.target.document.intended_std_level as lvl %}
{% with ref.target.intended_std_level as lvl %}
{% if lvl %}{{ lvl }}{% endif %}
{% endwith %}
{% endif %}

View file

@ -52,7 +52,7 @@
<td class="edit"></td>
<td>
{% for rel in relation_group.list %}
{{ rel.target.document.canonical_name|upper|urlize_ietf_docs }}{% if not forloop.last %},{% endif %}
{{ rel.target.canonical_name|upper|urlize_ietf_docs }}{% if not forloop.last %},{% endif %}
{% endfor %}
</td>
</tr>

View file

@ -33,7 +33,7 @@ No IPR declarations have been submitted directly on this I-D.
{% if downrefs %}
The document contains these normative downward references.
See RFC 3967 for additional information:
{% for ref in downrefs %} {{ref.target.document.canonical_name}}: {{ref.target.document.title}} ({{ref.target.document.std_level}} - {{ref.target.document.stream.desc}})
{% for ref in downrefs %} {{ref.target.canonical_name}}: {{ref.target.title}} ({{ref.target.std_level}} - {{ref.target.stream.desc}})
{% endfor %}{%endif%}
{% endautoescape %}

View file

@ -1,11 +1,11 @@
{% load ietf_filters %}{% load mail_filters %}{% autoescape off %}From: The IESG <iesg-secretary@ietf.org>
To: {{ to }}{% if cc %}
Cc: {{ cc }}{% endif %}
Subject: {{action}}: {{relateddoc.target.document.title}} to {{newstatus}}
Subject: {{action}}: {{relateddoc.target.title}} to {{newstatus}}
{% filter wordwrap:78 %}The IESG has approved changing the status of the following document:
- {{relateddoc.target.document.title }}
({{relateddoc.target.document.canonical_name }}) to {{ newstatus }}
- {{relateddoc.target.title }}
({{relateddoc.target.canonical_name }}) to {{ newstatus }}
This {{action|lower}} is documented at:
{{status_change_url}}

View file

@ -165,13 +165,13 @@ Parts Copyright (c) 2009 The IETF Trust, all rights reserved.
{% if downrefs %}
<p>If APPROVED - The Secretariat will add to the downref registry:<br>
{% for ref in downrefs %}
+ Add {{ref.target.document.canonical_name}}
({{ref.target.document.std_level}} - {{ref.target.document.stream.desc}})
+ Add {{ref.target.canonical_name}}
({{ref.target.std_level}} - {{ref.target.stream.desc}})
to downref registry.<br>
{% if not ref.target.document.std_level %}
{% if not ref.target.std_level %}
+++ Warning: The standards level has not been set yet!!!<br>
{% endif %}
{% if not ref.target.document.stream %}
{% if not ref.target.stream %}
+++ Warning: document stream has not been set yet!!!<br>
{% endif %}
{% endfor %}</p>

View file

@ -12,11 +12,12 @@ from django.utils.encoding import smart_str
import debug # pyflakes:ignore
from ietf.doc.models import Document, DocAlias, State, DocumentAuthor, DocEvent, RelatedDocument, NewRevisionDocEvent
from ietf.doc.factories import IndividualDraftFactory, ConflictReviewFactory, StatusChangeFactory, WgDraftFactory, WgRfcFactory
from ietf.group.models import Group, GroupHistory, Role, RoleHistory
from ietf.iesg.models import TelechatDate
from ietf.ipr.models import HolderIprDisclosure, IprDocRel, IprDisclosureStateName, IprLicenseTypeName
from ietf.meeting.models import Meeting, ResourceAssociation
from ietf.name.models import StreamName, DocRelationshipName, RoomResourceName, ConstraintName
from ietf.name.models import DocRelationshipName, RoomResourceName, ConstraintName
from ietf.person.models import Person, Email
from ietf.group.utils import setup_default_community_list_for_group
from ietf.review.models import (ReviewRequest, ReviewerSettings, ReviewResultName, ReviewTypeName, ReviewTeamSettings )
@ -316,7 +317,7 @@ def make_test_data():
doc_alias = DocAlias.objects.create(name=draft.name)
doc_alias.docs.add(draft)
RelatedDocument.objects.create(source=draft, target=old_alias, relationship=DocRelationshipName.objects.get(slug='replaces'))
RelatedDocument.objects.create(source=draft, target=old_draft, relationship=DocRelationshipName.objects.get(slug='replaces'))
old_draft.set_state(State.objects.get(type='draft', slug='repl'))
DocumentAuthor.objects.create(
@ -391,37 +392,27 @@ def make_test_data():
)
# an independent submission before review
doc = Document.objects.create(name='draft-imaginary-independent-submission',type_id='draft',rev='00',
title="Some Independent Notes on Imagination")
doc.set_state(State.objects.get(used=True, type="draft", slug="active"))
DocAlias.objects.create(name=doc.name).docs.add(doc)
IndividualDraftFactory(title="Some Independent Notes on Imagination")
# an irtf submission mid review
doc = Document.objects.create(name='draft-imaginary-irtf-submission', type_id='draft',rev='00',
stream=StreamName.objects.get(slug='irtf'), title="The Importance of Research Imagination")
docalias = DocAlias.objects.create(name=doc.name)
docalias.docs.add(doc)
doc.set_state(State.objects.get(type="draft", slug="active"))
crdoc = Document.objects.create(name='conflict-review-imaginary-irtf-submission', type_id='conflrev',
rev='00', notify="fsm@ietf.org", title="Conflict Review of IRTF Imagination Document")
DocAlias.objects.create(name=crdoc.name).docs.add(crdoc)
crdoc.set_state(State.objects.get(name='Needs Shepherd', type__slug='conflrev'))
crdoc.relateddocument_set.create(target=docalias,relationship_id='conflrev')
doc = IndividualDraftFactory(name="draft-imaginary-irtf-submission", stream_id="irtf", title="The Importance of Research Imagination")
ConflictReviewFactory(name="conflict-review-imaginary-irtf-submission", review_of=doc, notify="fsm@ietf.org", title="Conflict Review of IRTF Imagination Document")
# A status change mid review
iesg = Group.objects.get(acronym='iesg')
doc = Document.objects.create(name='status-change-imaginary-mid-review',type_id='statchg', rev='00',
notify="fsm@ietf.org", group=iesg, title="Status Change Review without Imagination")
doc.set_state(State.objects.get(slug='needshep',type__slug='statchg'))
docalias = DocAlias.objects.create(name='status-change-imaginary-mid-review')
docalias.docs.add(doc)
doc = StatusChangeFactory(
name='status-change-imaginary-mid-review',
notify="fsm@ietf.org",
group=iesg,
title="Status Change Review without Imagination",
states= [State.objects.get(type_id="statchg",slug="needshep")]
)
# Some things for a status change to affect
def rfc_for_status_change_test_factory(name,rfc_num,std_level_id):
target_rfc = Document.objects.create(name=name, type_id='draft', std_level_id=std_level_id, notify="%s@ietf.org"%name)
target_rfc.set_state(State.objects.get(slug='rfc',type__slug='draft'))
DocAlias.objects.create(name=name).docs.add(target_rfc)
DocAlias.objects.create(name='rfc%d'%rfc_num).docs.add(target_rfc)
target_rfc = WgRfcFactory(rfc_number=rfc_num, std_level_id=std_level_id)
source_draft = WgDraftFactory(name=name, states=[("draft","rfc")], notify=f"{name}@ietf.org")
source_draft.relateddocument_set.create(relationship_id="became_rfc", target=target_rfc)
return target_rfc
rfc_for_status_change_test_factory('draft-ietf-random-thing',9999,'ps')
rfc_for_status_change_test_factory('draft-ietf-random-otherthing',9998,'inf')