aboutsummaryrefslogtreecommitdiffstats
path: root/backend/routes/forms/submit.py
diff options
context:
space:
mode:
authorGravatar Hassan Abouelela <[email protected]>2021-06-20 21:12:47 +0300
committerGravatar GitHub <[email protected]>2021-06-20 21:12:47 +0300
commitaf65bd5584e4a02057374b344e5d055bc799ba60 (patch)
tree2b3658d1dd491d6cc2c967c59a3fe237cac4281e /backend/routes/forms/submit.py
parentMerge pull request #90 from python-discord/auth-form (diff)
parentUpdates Unittest Filter To Match New Model (diff)
Merge pull request #92 from python-discord/unittest_failures
Allow Unittest Failures
Diffstat (limited to 'backend/routes/forms/submit.py')
-rw-r--r--backend/routes/forms/submit.py57
1 files changed, 50 insertions, 7 deletions
diff --git a/backend/routes/forms/submit.py b/backend/routes/forms/submit.py
index c0a50f3..7229ee1 100644
--- a/backend/routes/forms/submit.py
+++ b/backend/routes/forms/submit.py
@@ -45,6 +45,18 @@ class PartialSubmission(BaseModel):
captcha: Optional[str]
+class UnittestError(BaseModel):
+ question_id: str
+ question_index: int
+ return_code: int
+ passed: bool
+ result: str
+
+
+class UnittestErrorMessage(ErrorMessage):
+ test_results: list[UnittestError]
+
+
class SubmitForm(Route):
"""
Submit a form with the provided form ID.
@@ -58,7 +70,8 @@ class SubmitForm(Route):
resp=Response(
HTTP_200=SubmissionResponse,
HTTP_404=ErrorMessage,
- HTTP_400=ErrorMessage
+ HTTP_400=ErrorMessage,
+ HTTP_422=UnittestErrorMessage
),
tags=["forms", "responses"]
)
@@ -168,16 +181,46 @@ class SubmitForm(Route):
if any("unittests" in question.data for question in form.questions):
unittest_results = await execute_unittest(response_obj, form)
- if not all(test.passed for test in unittest_results):
- # Return 500 if we encountered an internal error (code 99).
- status_code = 500 if any(
- test.return_code == 99 for test in unittest_results
- ) else 403
+ failures = []
+ status_code = 422
+
+ for test in unittest_results:
+ response_obj.response[test.question_id] = {
+ "value": response_obj.response[test.question_id],
+ "passed": test.passed
+ }
+
+ if test.return_code == 0:
+ failure_names = [] if test.passed else test.result.split(";")
+ elif test.return_code == 5:
+ failure_names = ["Could not parse user code."]
+ elif test.return_code == 6:
+ failure_names = ["Could not load user code."]
+ else:
+ failure_names = ["Internal error."]
+
+ response_obj.response[test.question_id]["failures"] = failure_names
+
+ # Report a failure on internal errors,
+ # or if the test suite doesn't allow failures
+ if not test.passed:
+ allow_failure = (
+ form.questions[test.question_index].data["unittests"]["allow_failure"]
+ )
+
+ # An error while communicating with the test runner
+ if test.return_code == 99:
+ failures.append(test)
+ status_code = 500
+
+ elif not allow_failure:
+ failures.append(test)
+ if len(failures):
return JSONResponse({
"error": "failed_tests",
"test_results": [
- test._asdict() for test in unittest_results if not test.passed
+ test._asdict() for test in failures
]
}, status_code=status_code)