Coverage for tests/test_exceptions.py: 100%

45 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-11-13 19:28 +0000

1"""Tests for core exceptions module.""" 

2 

3import pytest 

4 

5from data_api.core.exceptions import ( 

6 DataAPIException, 

7 DataNotAvailableException, 

8 DataUpdateException, 

9 UpstreamException, 

10 UpstreamResponseException, 

11 UpstreamTimeoutException, 

12) 

13 

14 

15class TestDataAPIException: 

16 """Tests for DataAPIException.""" 

17 

18 async def test_base_exception(self): 

19 """Test DataAPIException can be raised and caught.""" 

20 with pytest.raises(DataAPIException) as exc_info: 

21 raise DataAPIException("Test error") 

22 assert "Test error" in str(exc_info.value) 

23 

24 async def test_base_exception_inheritance(self): 

25 """Test DataAPIException inherits from Exception.""" 

26 exc = DataAPIException("Test") 

27 assert isinstance(exc, Exception) 

28 

29 

30class TestDataNotAvailableException: 

31 """Tests for DataNotAvailableException.""" 

32 

33 async def test_data_not_available(self): 

34 """Test DataNotAvailableException can be raised.""" 

35 with pytest.raises(DataNotAvailableException) as exc_info: 

36 raise DataNotAvailableException("Data unavailable") 

37 assert "Data unavailable" in str(exc_info.value) 

38 

39 async def test_inheritance(self): 

40 """Test it inherits from DataAPIException.""" 

41 exc = DataNotAvailableException("Test") 

42 assert isinstance(exc, DataAPIException) 

43 

44 

45class TestDataUpdateException: 

46 """Tests for DataUpdateException.""" 

47 

48 async def test_data_update_exception(self): 

49 """Test DataUpdateException can be raised.""" 

50 with pytest.raises(DataUpdateException) as exc_info: 

51 raise DataUpdateException("Update failed") 

52 assert "Update failed" in str(exc_info.value) 

53 

54 async def test_inheritance(self): 

55 """Test it inherits from DataAPIException.""" 

56 exc = DataUpdateException("Test") 

57 assert isinstance(exc, DataAPIException) 

58 

59 

60class TestExceptionHierarchy: 

61 """Tests for exception hierarchy.""" 

62 

63 async def test_catch_specific_with_base(self): 

64 """Test catching specific exceptions with base exception.""" 

65 try: 

66 raise DataNotAvailableException("Test") 

67 except DataAPIException as e: 

68 assert isinstance(e, DataNotAvailableException) 

69 

70 async def test_catch_data_update_with_base(self): 

71 """Test catching DataUpdateException with base exception.""" 

72 try: 

73 raise DataUpdateException("Test") 

74 except DataAPIException as e: 

75 assert isinstance(e, DataUpdateException) 

76 

77 

78@pytest.mark.parametrize( 

79 "exception,status,detail", 

80 [ 

81 (UpstreamException, 502, "Upstream service unavailable"), 

82 (UpstreamTimeoutException, 504, "Upstream request timed out"), 

83 (UpstreamResponseException, 502, "Invalid response from upstream service"), 

84 ], 

85) 

86def test_upstream_exceptions_keep_public_details_safe(exception, status, detail): 

87 exc = exception("Private diagnostic at https://upstream.example") 

88 assert isinstance(exc, DataAPIException) 

89 assert isinstance(exc, UpstreamException) 

90 assert exc.status_code == status 

91 assert exc.detail == detail 

92 assert "Private diagnostic" in str(exc)