File size: 12,163 Bytes
b216c95 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
"""
Unit tests for common.exceptions module
Tests all custom exception classes and their attributes.
"""
import pytest
from common import (
MedicalTranscriberException,
AudioFileException,
TranscriptionException,
CorrectionException,
ReportGenerationException,
ConfigurationException,
APIException,
ValidationException,
KnowledgeBaseException
)
class TestMedicalTranscriberException:
"""Test cases for base MedicalTranscriberException"""
def test_is_exception(self):
"""Should be an Exception subclass"""
exc = MedicalTranscriberException("Test error")
assert isinstance(exc, Exception)
def test_with_message(self):
"""Should accept message"""
msg = "Test error message"
exc = MedicalTranscriberException(msg)
assert str(exc) == msg
def test_inheritance(self):
"""All specific exceptions should inherit from base"""
exceptions = [
AudioFileException("path", "message"),
TranscriptionException("message"),
CorrectionException("message"),
ReportGenerationException("message"),
ConfigurationException("message"),
APIException("endpoint", 404, "message"),
ValidationException("field", "value", "message"),
KnowledgeBaseException("message")
]
for exc in exceptions:
assert isinstance(exc, MedicalTranscriberException)
class TestAudioFileException:
"""Test cases for AudioFileException"""
def test_with_default_message(self):
"""Should use default message if not provided"""
exc = AudioFileException("/path/to/file.wav")
assert "/path/to/file.wav" in str(exc)
assert "Invalid audio file" in str(exc)
def test_with_custom_message(self):
"""Should use custom message if provided"""
exc = AudioFileException("/path/to/file.wav", "File is corrupted")
assert "File is corrupted" in str(exc)
assert "/path/to/file.wav" in str(exc)
def test_file_path_attribute(self):
"""Should have file_path attribute"""
file_path = "/path/to/file.wav"
exc = AudioFileException(file_path, "Test")
assert exc.file_path == file_path
def test_message_attribute(self):
"""Should have message attribute"""
exc = AudioFileException("/path/to/file.wav", "Test message")
assert "Test message" in exc.message
class TestTranscriptionException:
"""Test cases for TranscriptionException"""
def test_basic_usage(self):
"""Should work with simple message"""
exc = TranscriptionException("Transcription failed")
assert "Transcription failed" in str(exc)
def test_inheritance_chain(self):
"""Should be MedicalTranscriberException"""
exc = TranscriptionException("Test")
assert isinstance(exc, MedicalTranscriberException)
class TestCorrectionException:
"""Test cases for CorrectionException"""
def test_basic_usage(self):
"""Should work with simple message"""
exc = CorrectionException("LLM correction failed")
assert "LLM correction failed" in str(exc)
def test_inheritance_chain(self):
"""Should be MedicalTranscriberException"""
exc = CorrectionException("Test")
assert isinstance(exc, MedicalTranscriberException)
class TestReportGenerationException:
"""Test cases for ReportGenerationException"""
def test_basic_usage(self):
"""Should work with simple message"""
exc = ReportGenerationException("Report generation failed")
assert "Report generation failed" in str(exc)
def test_inheritance_chain(self):
"""Should be MedicalTranscriberException"""
exc = ReportGenerationException("Test")
assert isinstance(exc, MedicalTranscriberException)
class TestConfigurationException:
"""Test cases for ConfigurationException"""
def test_basic_usage(self):
"""Should work with simple message"""
exc = ConfigurationException("Invalid configuration")
assert "Invalid configuration" in str(exc)
def test_inheritance_chain(self):
"""Should be MedicalTranscriberException"""
exc = ConfigurationException("Test")
assert isinstance(exc, MedicalTranscriberException)
class TestAPIException:
"""Test cases for APIException with status codes"""
def test_with_status_code_and_message(self):
"""Should capture endpoint, status code, and message"""
exc = APIException("https://api.example.com/v1/chat", 429, "Rate limit exceeded")
assert exc.endpoint == "https://api.example.com/v1/chat"
assert exc.status_code == 429
assert "429" in str(exc)
assert "Rate limit" in str(exc)
def test_error_400(self):
"""Should handle 400 Bad Request"""
exc = APIException("api/endpoint", 400, "Bad request format")
assert exc.status_code == 400
assert "400" in str(exc)
def test_error_401(self):
"""Should handle 401 Unauthorized"""
exc = APIException("api/endpoint", 401, "Invalid API key")
assert exc.status_code == 401
assert "401" in str(exc)
assert "Invalid API key" in str(exc)
def test_error_429(self):
"""Should handle 429 Rate Limit"""
exc = APIException("api/endpoint", 429, "Rate limit exceeded")
assert exc.status_code == 429
assert "429" in str(exc)
def test_error_500(self):
"""Should handle 500 Internal Server Error"""
exc = APIException("api/endpoint", 500, "Server error")
assert exc.status_code == 500
assert "500" in str(exc)
def test_message_attribute(self):
"""Should have message attribute with full context"""
exc = APIException("api/endpoint", 404, "Not found")
assert "404" in exc.message
assert "api/endpoint" in exc.message
def test_inheritance_chain(self):
"""Should be MedicalTranscriberException"""
exc = APIException("api", 500, "error")
assert isinstance(exc, MedicalTranscriberException)
class TestValidationException:
"""Test cases for ValidationException with field context"""
def test_with_field_name(self):
"""Should capture field name"""
exc = ValidationException("email", "invalid@", "Invalid email format")
assert exc.field == "email"
assert exc.value == "invalid@"
assert "email" in str(exc)
def test_default_reason(self):
"""Should use default reason if not provided"""
exc = ValidationException("username", "ab", "")
assert "Invalid value" in str(exc)
def test_custom_reason(self):
"""Should use custom reason"""
exc = ValidationException("age", "-5", "Age must be positive")
assert "Age must be positive" in str(exc)
def test_audio_file_field(self):
"""Should work with audio_file field"""
exc = ValidationException("audio_file", "test.xyz", "Unsupported format")
assert "audio_file" in str(exc)
assert "test.xyz" in str(exc)
def test_api_key_field(self):
"""Should work with api_key field"""
exc = ValidationException("api_key", "***", "API key is too short")
assert "api_key" in str(exc)
def test_inheritance_chain(self):
"""Should be MedicalTranscriberException"""
exc = ValidationException("field", "value", "reason")
assert isinstance(exc, MedicalTranscriberException)
class TestKnowledgeBaseException:
"""Test cases for KnowledgeBaseException"""
def test_basic_usage(self):
"""Should work with simple message"""
exc = KnowledgeBaseException("Knowledge base not found")
assert "Knowledge base not found" in str(exc)
def test_inheritance_chain(self):
"""Should be MedicalTranscriberException"""
exc = KnowledgeBaseException("Test")
assert isinstance(exc, MedicalTranscriberException)
class TestExceptionHandling:
"""Integration tests for exception handling"""
def test_catch_api_exception_by_status_code(self):
"""Should be able to catch and handle by status code"""
exc = APIException("api/chat", 429, "Rate limit")
try:
raise exc
except APIException as e:
if e.status_code == 429:
assert True
else:
assert False
def test_catch_specific_exceptions(self):
"""Should be able to catch specific exception types"""
exceptions_to_test = [
(AudioFileException("/path", "test"), AudioFileException),
(TranscriptionException("test"), TranscriptionException),
(CorrectionException("test"), CorrectionException),
(APIException("api", 500, "error"), APIException),
(ValidationException("field", "value", "reason"), ValidationException),
]
for exc, exc_type in exceptions_to_test:
try:
raise exc
except exc_type:
assert True
except Exception:
assert False
def test_catch_all_as_medical_transcriber_exception(self):
"""Should be able to catch all as base exception"""
exceptions = [
AudioFileException("/path", "test"),
TranscriptionException("test"),
CorrectionException("test"),
APIException("api", 500, "error"),
ValidationException("field", "value", "reason"),
KnowledgeBaseException("test"),
]
for exc in exceptions:
try:
raise exc
except MedicalTranscriberException:
assert True
except Exception:
assert False
def test_exception_chain_preservation(self):
"""Should preserve exception chain"""
try:
try:
raise ValueError("Original error")
except ValueError as e:
raise AudioFileException("/path", str(e)) from e
except AudioFileException as e:
assert str(e.file_path) == "/path"
def test_multiple_exception_handlers(self):
"""Should work with multiple exception handlers"""
def test_api_error():
raise APIException("api", 429, "Rate limited")
def test_validation_error():
raise ValidationException("field", "value", "Invalid")
try:
test_api_error()
except APIException as e:
assert e.status_code == 429
except Exception:
assert False
try:
test_validation_error()
except ValidationException as e:
assert e.field == "field"
except Exception:
assert False
class TestExceptionStringRepresentation:
"""Test string representations of exceptions"""
def test_audio_file_exception_string(self):
"""Should have informative string representation"""
exc = AudioFileException("/path/to/audio.wav", "Corrupted file")
exc_str = str(exc)
assert "Corrupted file" in exc_str
assert "/path/to/audio.wav" in exc_str
def test_api_exception_string(self):
"""Should have informative string representation"""
exc = APIException("api/v1/chat", 401, "Unauthorized")
exc_str = str(exc)
assert "401" in exc_str
assert "api/v1/chat" in exc_str
assert "Unauthorized" in exc_str
def test_validation_exception_string(self):
"""Should have informative string representation"""
exc = ValidationException("username", "admin", "Username reserved")
exc_str = str(exc)
assert "username" in exc_str
assert "admin" in exc_str
assert "Username reserved" in exc_str
|