Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions qa/qa/checks/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ class Result(BaseModel):
offsets: list[Offset] | None = None
results: list["Result"] | None = None

def failure_messages(self, *dispositions: Disposition) -> str:
"""Return a concatenated string containing all messages for failed results with the given dispositions."""
if not self.results:
return self.message if not self.passed else ""
return "\n".join(r.message for r in self.results if not r.passed and r.disposition in dispositions)


class Flag(BaseModel):
id: str = Field(pattern=kebab_case)
Expand Down
77 changes: 76 additions & 1 deletion qa/tests/checks/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from pydantic import ValidationError
from unittest import TestCase

from qa.checks.models import BaseReport, Flag
from qa.checks.models import BaseReport, Disposition, Flag, Result


def base_report(
Expand Down Expand Up @@ -39,6 +39,81 @@ def test_submission_id_must_be_positive(self):
base_report(submission_id=0)


class TestResultFailureMessages(TestCase):
def test_no_results_and_passed_returns_empty_string(self):
result = Result(check_config={}, passed=True, disposition=Disposition.OK, message="")
self.assertEqual(result.failure_messages(Disposition.WARN, Disposition.REJECT), "")

def test_no_results_and_failed_returns_own_message(self):
result = Result(check_config={}, passed=False, disposition=Disposition.REJECT, message="own message")
self.assertEqual(result.failure_messages(Disposition.WARN, Disposition.REJECT), "own message")

def test_no_dispositions_returns_empty_string(self):
result = Result(
check_config={},
passed=False,
disposition=Disposition.REJECT,
message="",
results=[
Result(check_config={}, passed=False, disposition=Disposition.REJECT, message="reject message"),
],
)
self.assertEqual(result.failure_messages(), "")

def test_concatenates_messages_matching_given_dispositions(self):
result = Result(
check_config={},
passed=False,
disposition=Disposition.REJECT,
message="",
results=[
Result(check_config={}, passed=False, disposition=Disposition.WARN, message="warn message"),
Result(check_config={}, passed=False, disposition=Disposition.REJECT, message="reject message"),
],
)
self.assertEqual(result.failure_messages(Disposition.WARN, Disposition.REJECT), "warn message\nreject message")

def test_filters_to_a_single_disposition(self):
result = Result(
check_config={},
passed=False,
disposition=Disposition.REJECT,
message="",
results=[
Result(check_config={}, passed=False, disposition=Disposition.WARN, message="warn message"),
Result(check_config={}, passed=False, disposition=Disposition.REJECT, message="reject message"),
],
)
self.assertEqual(result.failure_messages(Disposition.REJECT), "reject message")

def test_excludes_passed_and_ignored_sub_checks(self):
result = Result(
check_config={},
passed=True,
disposition=Disposition.OK,
message="",
results=[
Result(check_config={}, passed=True, disposition=Disposition.OK, message="passed message"),
Result(check_config={}, passed=False, disposition=Disposition.OK, message="ignored message"),
Result(check_config={}, passed=False, disposition=Disposition.WARN, message="warn message"),
],
)
self.assertEqual(result.failure_messages(Disposition.WARN, Disposition.REJECT), "warn message")

def test_excludes_passed_sub_checks_even_with_matching_disposition(self):
result = Result(
check_config={},
passed=True,
disposition=Disposition.OK,
message="",
results=[
Result(check_config={}, passed=True, disposition=Disposition.OK, message="passed message"),
Result(check_config={}, passed=False, disposition=Disposition.OK, message="ignored message"),
],
)
self.assertEqual(result.failure_messages(Disposition.OK), "ignored message")


class TestFlag(TestCase):
def test_id_rejects_underscores(self):
with self.assertRaises(ValidationError):
Expand Down
Loading