Coverage for server / validators / assignment_validator.py: 97%
39 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-10-04 09:33 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-10-04 09:33 +0000
1from fastapi import HTTPException, status
2from typing import Dict, Any
5def validate_assignment_fields(values: Dict[str, Any]) -> Dict[str, Any]:
6 """
7 Validates that all required assignment fields are not empty or whitespace-only.
9 Required fields:
10 - semester
11 - type
12 - category
13 - format
14 - title
15 - description
16 - questions
17 - assigned_class
18 - settings
20 Args:
21 values (Dict[str, Any]): Dictionary containing assignment fields
23 Returns:
24 Dict[str, Any]: The validated values dictionary
26 Raises:
27 HTTPException: If any required field is empty or contains only whitespace
28 """
29 required_fields = [
30 "semester",
31 "type",
32 "category",
33 "format",
34 "title",
35 "description",
36 "questions",
37 "assigned_class",
38 "settings"
39 ]
41 for field in required_fields:
42 if field not in values or values[field] is None:
43 raise HTTPException(
44 status_code=status.HTTP_400_BAD_REQUEST,
45 detail=f"{field} field is required and cannot be empty"
46 )
48 # Check for empty strings or whitespace-only strings
49 if isinstance(values[field], str) and values[field].strip() == "":
50 raise HTTPException(
51 status_code=status.HTTP_400_BAD_REQUEST,
52 detail=f"{field} field cannot contain only whitespace"
53 )
55 # Special handling for lists
56 if field in ["questions", "assigned_class"] and isinstance(values[field], list):
57 if len(values[field]) == 0:
58 raise HTTPException(
59 status_code=status.HTTP_400_BAD_REQUEST,
60 detail=f"{field} field is required and cannot be empty"
61 )
63 # Validate settings fields
64 if "settings" in values and values["settings"] is not None:
65 settings = values["settings"]
66 settings_fields = [
67 "allowed_attempts",
68 "shuffle_questions",
69 "shuffle_choices",
70 "allow_calculator",
71 "show_score_after_submit",
72 "show_correct_answers_after_submit",
73 "allow_feedback_after_submit"
74 ]
76 for field in settings_fields:
77 if field not in settings or settings[field] is None:
78 if field == "time_allowed":
79 raise HTTPException(
80 status_code=status.HTTP_400_BAD_REQUEST,
81 detail="time_allowed field is required"
82 )
83 else:
84 raise HTTPException(
85 status_code=status.HTTP_400_BAD_REQUEST,
86 detail=f"settings.{field} field is required and cannot be empty"
87 )
89 return values
92def validate_submission_fields(values: Dict[str, Any]) -> Dict[str, Any]:
93 """
94 Validates that all required submission fields are not empty or whitespace-only.
96 Required fields:
97 - assignment_id
98 - answers
100 Args:
101 values (Dict[str, Any]): Dictionary containing submission fields
103 Returns:
104 Dict[str, Any]: The validated values dictionary
106 Raises:
107 HTTPException: If any required field is empty or contains only whitespace
108 """
109 required_fields = ["assignment_id", "answers"]
111 for field in required_fields:
112 if field not in values or values[field] is None:
113 raise HTTPException(
114 status_code=status.HTTP_400_BAD_REQUEST,
115 detail=f"{field} field is required and cannot be empty"
116 )
118 # Check for empty strings or whitespace-only strings
119 if isinstance(values[field], str) and values[field].strip() == "":
120 raise HTTPException(
121 status_code=status.HTTP_400_BAD_REQUEST,
122 detail=f"{field} field cannot contain only whitespace"
123 )
125 # Special handling for answers list
126 if field == "answers" and isinstance(values[field], list):
127 if len(values[field]) == 0:
128 raise HTTPException(
129 status_code=status.HTTP_400_BAD_REQUEST,
130 detail=f"{field} field is required and cannot be empty"
131 )
133 # Validate each answer
134 for i, answer in enumerate(values[field]):
135 answer_fields = ["question_id", "user_answer", "is_correct"]
136 for answer_field in answer_fields:
137 if answer_field not in answer or answer[answer_field] is None:
138 raise HTTPException(
139 status_code=status.HTTP_400_BAD_REQUEST,
140 detail=f"answers[{i}].{answer_field} field is required and cannot be empty"
141 )
143 # Check for empty strings or whitespace-only strings in string fields
144 if answer_field in ["question_id", "user_answer"] and isinstance(answer[answer_field], str) and answer[answer_field].strip() == "":
145 raise HTTPException(
146 status_code=status.HTTP_400_BAD_REQUEST,
147 detail=f"answers[{i}].{answer_field} field cannot contain only whitespace"
148 )
150 return values