feat: Distinguish failed from not-applied checkers (#6220)
* feat: Distinguish failed from not-applied checkers * refactor: Only return applied checks from latest_checks() * refactor: Use latest_checks() in submission_status view * chore: Fix incorrectly phrased comment * test: Test submission check summary
This commit is contained in:
parent
5d08378b5a
commit
7f8cbaa211
|
@ -79,11 +79,18 @@ class Submission(models.Model):
|
|||
return Document.objects.filter(name=self.name).first()
|
||||
|
||||
def latest_checks(self):
|
||||
checks = [ self.checks.filter(checker=c).latest('time') for c in self.checks.values_list('checker', flat=True).distinct() ]
|
||||
return checks
|
||||
"""Latest check of each type, excluding any that did not apply
|
||||
|
||||
Ignores any checks where passed is None
|
||||
"""
|
||||
latest_for_each_checker = [
|
||||
self.checks.filter(checker=c).latest("time")
|
||||
for c in self.checks.values_list("checker", flat=True).distinct()
|
||||
]
|
||||
return [check for check in latest_for_each_checker if check.passed is not None]
|
||||
|
||||
def has_yang(self):
|
||||
return any ( [ c.checker=='yang validation' and c.passed is not None for c in self.latest_checks()] )
|
||||
return any(c.checker == "yang validation" for c in self.latest_checks())
|
||||
|
||||
@property
|
||||
def replaces_names(self):
|
||||
|
|
|
@ -3808,3 +3808,54 @@ class TestOldNamesAreProtected(BaseSubmitTestCase):
|
|||
files["xml"], _ = submission_file("draft-something-hascapitalletters-00", "draft-something-hascapitalletters-00.xml", None, "test_submission.xml")
|
||||
r = self.post_to_upload_submission(url, files)
|
||||
self.assertContains(r,"Case-conflicting draft name found",status_code=200)
|
||||
|
||||
|
||||
class SubmissionStatusTests(BaseSubmitTestCase):
|
||||
"""Tests of the submission_status view
|
||||
|
||||
Many tests are interspersed in the monolithic tests above. We can aspire to break these
|
||||
out more modularly, though.
|
||||
"""
|
||||
|
||||
def test_submission_checks(self):
|
||||
for state_slug in ("uploaded", "cancel", "posted"):
|
||||
submission = SubmissionFactory(state_id=state_slug)
|
||||
url = urlreverse(
|
||||
"ietf.submit.views.submission_status",
|
||||
kwargs={"submission_id": submission.pk},
|
||||
)
|
||||
# No checks
|
||||
r = self.client.get(url)
|
||||
self.assertContains(
|
||||
r,
|
||||
"No submission checks were applied to your Internet-Draft.",
|
||||
status_code=200,
|
||||
)
|
||||
# Inapplicable check
|
||||
submission.checks.create(
|
||||
checker="yang validation", passed=None, message="Yang message"
|
||||
)
|
||||
r = self.client.get(url)
|
||||
self.assertContains(
|
||||
r,
|
||||
"No submission checks were applied to your Internet-Draft.",
|
||||
status_code=200,
|
||||
)
|
||||
# Passed check
|
||||
submission.checks.create(
|
||||
checker="idnits check", passed=True, message="idnits ok"
|
||||
)
|
||||
r = self.client.get(url)
|
||||
self.assertContains(
|
||||
r,
|
||||
"Your Internet-Draft has been verified to pass the submission checks.",
|
||||
status_code=200,
|
||||
)
|
||||
# Failed check + passed check
|
||||
submission.checks.filter(checker="yang validation").update(passed=False)
|
||||
r = self.client.get(url)
|
||||
self.assertContains(
|
||||
r,
|
||||
"Your Internet-Draft failed at least one submission check.",
|
||||
status_code=200,
|
||||
)
|
||||
|
|
|
@ -321,7 +321,9 @@ def submission_status(request, submission_id, access_token=None):
|
|||
errors = {}
|
||||
else:
|
||||
errors = validate_submission(submission)
|
||||
passes_checks = all([ c.passed!=False for c in submission.checks.all() ])
|
||||
latest_checks = submission.latest_checks()
|
||||
applied_any_checks = len(latest_checks) > 0
|
||||
passes_checks = applied_any_checks and all(c.passed for c in latest_checks)
|
||||
|
||||
is_secretariat = has_role(request.user, "Secretariat")
|
||||
is_chair = submission.group and submission.group.has_role(request.user, "chair")
|
||||
|
@ -547,6 +549,7 @@ def submission_status(request, submission_id, access_token=None):
|
|||
'selected': 'status',
|
||||
'submission': submission,
|
||||
'errors': errors,
|
||||
'applied_any_checks': applied_any_checks,
|
||||
'passes_checks': passes_checks,
|
||||
'submitter_form': submitter_form,
|
||||
'replaces_form': replaces_form,
|
||||
|
|
|
@ -40,8 +40,10 @@
|
|||
<p class="alert {% if passes_checks %}alert-success{% else %}alert-warning{% endif %} my-3">
|
||||
{% if passes_checks %}
|
||||
Your Internet-Draft has been verified to pass the submission checks.
|
||||
{% elif applied_any_checks %}
|
||||
Your Internet-Draft failed at least one submission check.
|
||||
{% else %}
|
||||
Your Internet-Draft has <b>NOT</b> been verified to pass the submission checks.
|
||||
No submission checks were applied to your Internet-Draft.
|
||||
{% endif %}
|
||||
</p>
|
||||
{% if submission.authors|length > 5 %}
|
||||
|
@ -70,41 +72,39 @@
|
|||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for check in submission.latest_checks %}
|
||||
{% if check.passed != None %}
|
||||
<button class="btn btn-{% if check.passed %}{% if check.warnings %}warning{% elif check.errors %}danger{% else %}success{% endif %}{% else %}danger{% endif %}"
|
||||
type="button"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#check-{{ check.pk }}">
|
||||
View {{ check.checker }}
|
||||
</button>
|
||||
<div class="modal fade"
|
||||
id="check-{{ check.pk }}"
|
||||
tabindex="-1"
|
||||
role="dialog"
|
||||
aria-labelledby="check-{{ check.pk }}"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-scrollable modal-xl">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<p class="h5 modal-title" id="{{ check.checker|slugify }}-label">
|
||||
{{ check.checker|title }} for {{ submission.name }}-{{ submission.rev }}
|
||||
</p>
|
||||
<button type="button"
|
||||
class="btn-close"
|
||||
data-bs-dismiss="modal"
|
||||
aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body" id="{{ check.checker|slugify }}-message">
|
||||
<pre>{{ check.message|urlize_ietf_docs|linkify }}</pre>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
</div>
|
||||
<button class="btn btn-{% if check.passed %}{% if check.warnings %}warning{% elif check.errors %}danger{% else %}success{% endif %}{% else %}danger{% endif %}"
|
||||
type="button"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#check-{{ check.pk }}">
|
||||
View {{ check.checker }}
|
||||
</button>
|
||||
<div class="modal fade"
|
||||
id="check-{{ check.pk }}"
|
||||
tabindex="-1"
|
||||
role="dialog"
|
||||
aria-labelledby="check-{{ check.pk }}"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-scrollable modal-xl">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<p class="h5 modal-title" id="{{ check.checker|slugify }}-label">
|
||||
{{ check.checker|title }} for {{ submission.name }}-{{ submission.rev }}
|
||||
</p>
|
||||
<button type="button"
|
||||
class="btn-close"
|
||||
data-bs-dismiss="modal"
|
||||
aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body" id="{{ check.checker|slugify }}-message">
|
||||
<pre>{{ check.message|urlize_ietf_docs|linkify }}</pre>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<div class="modal fade"
|
||||
id="twopages"
|
||||
|
|
Loading…
Reference in a new issue