11"""Unit tests for get_harmony_job_status module"""
2+ from unittest .mock import MagicMock , patch
3+
24import pytest
5+ import requests
36from moto import mock_s3
47
58import bignbit .utils
6- from bignbit .get_harmony_job_status import check_harmony_job , HarmonyJobNoDataError
9+ from bignbit .get_harmony_job_status import (
10+ check_harmony_job ,
11+ HarmonyJobNoDataError ,
12+ HarmonyTransientError ,
13+ )
714
815
916@pytest .mark .vcr
@@ -21,4 +28,75 @@ def test_process_results_no_data():
2128
2229 assert 'no data' in str (exc_info .value ).lower ()
2330 assert 'test_variable' in str (exc_info .value )
24- assert 'EPSG:4326' in str (exc_info .value )
31+ assert 'EPSG:4326' in str (exc_info .value )
32+
33+
34+ def _make_http_error (status_code ):
35+ """Build a requests.exceptions.HTTPError with a mocked response."""
36+ response = MagicMock ()
37+ response .status_code = status_code
38+ error = requests .exceptions .HTTPError (response = response )
39+ return error
40+
41+
42+ @patch ('bignbit.get_harmony_job_status.utils.get_harmony_client' )
43+ def test_check_harmony_job_raises_transient_error_on_500 (mock_get_client ):
44+ """Test that HarmonyTransientError is raised when Harmony status returns a 500."""
45+ bignbit .utils .ED_USER = 'test'
46+ bignbit .utils .ED_PASS = 'test'
47+
48+ mock_client = MagicMock ()
49+ mock_client .status .side_effect = _make_http_error (500 )
50+ mock_get_client .return_value = mock_client
51+
52+ with pytest .raises (HarmonyTransientError ) as exc_info :
53+ check_harmony_job ('test-job-id' , 'uat' , 'test_variable' , 'EPSG:4326' )
54+
55+ assert 'transient error' in str (exc_info .value ).lower ()
56+ assert 'test-job-id' in str (exc_info .value )
57+
58+
59+ @patch ('bignbit.get_harmony_job_status.utils.get_harmony_client' )
60+ def test_check_harmony_job_raises_transient_error_on_503 (mock_get_client ):
61+ """Test that HarmonyTransientError is raised when Harmony status returns a 503."""
62+ bignbit .utils .ED_USER = 'test'
63+ bignbit .utils .ED_PASS = 'test'
64+
65+ mock_client = MagicMock ()
66+ mock_client .status .side_effect = _make_http_error (503 )
67+ mock_get_client .return_value = mock_client
68+
69+ with pytest .raises (HarmonyTransientError ):
70+ check_harmony_job ('test-job-id' , 'uat' , 'test_variable' , 'EPSG:4326' )
71+
72+
73+ @patch ('bignbit.get_harmony_job_status.utils.get_harmony_client' )
74+ def test_check_harmony_job_reraises_non_5xx_http_error (mock_get_client ):
75+ """Test that non-5xx HTTPErrors (e.g. 404) are re-raised without wrapping."""
76+ bignbit .utils .ED_USER = 'test'
77+ bignbit .utils .ED_PASS = 'test'
78+
79+ mock_client = MagicMock ()
80+ mock_client .status .side_effect = _make_http_error (404 )
81+ mock_get_client .return_value = mock_client
82+
83+ with pytest .raises (requests .exceptions .HTTPError ):
84+ check_harmony_job ('test-job-id' , 'uat' , 'test_variable' , 'EPSG:4326' )
85+
86+
87+ @patch ('bignbit.get_harmony_job_status.utils.get_harmony_client' )
88+ def test_check_harmony_job_result_urls_raises_transient_error_on_500 (mock_get_client ):
89+ """Test that HarmonyTransientError is raised when result_urls call returns a 500."""
90+ bignbit .utils .ED_USER = 'test'
91+ bignbit .utils .ED_PASS = 'test'
92+
93+ mock_client = MagicMock ()
94+ mock_client .status .return_value = {'status' : 'successful' }
95+ mock_client .result_urls .side_effect = _make_http_error (500 )
96+ mock_get_client .return_value = mock_client
97+
98+ with pytest .raises (HarmonyTransientError ) as exc_info :
99+ check_harmony_job ('test-job-id' , 'uat' , 'test_variable' , 'EPSG:4326' )
100+
101+ assert 'result urls' in str (exc_info .value ).lower ()
102+ assert 'test-job-id' in str (exc_info .value )
0 commit comments