11# pylint: disable=unused-argument
22import os
3- import warnings
3+ import pytest
44from unittest .mock import MagicMock , patch
55
66import matplotlib .pyplot as plt
7- import pytest
87
98plt .rcParams .update ({"figure.max_open_warning" : 0 })
109
@@ -13,6 +12,9 @@ def _post_test_file_cleanup():
1312 """Clean monte carlo files after test session if they exist."""
1413 files_to_cleanup = [
1514 "monte_carlo_test.png" ,
15+ "monte_carlo_test.errors.txt" ,
16+ "monte_carlo_test.inputs.txt" ,
17+ "monte_carlo_test.outputs.txt" ,
1618 ]
1719 for filepath in files_to_cleanup :
1820 if os .path .exists (filepath ):
@@ -152,10 +154,12 @@ def test_ellipses_image_takes_precedence_over_background(
152154 _post_test_file_cleanup ()
153155
154156
155- def test_ellipses_background_no_environment ():
157+ @patch ("matplotlib.pyplot.show" )
158+ def test_ellipses_background_no_environment (mock_show ):
156159 """Test that ValueError is raised when MonteCarlo object has no environment attribute.
157160
158161 This test creates a MonteCarlo object without an environment attribute.
162+ The function should raise ValueError when trying to fetch background map.
159163 """
160164 from rocketpy .plots .monte_carlo_plots import _MonteCarloPlots
161165
@@ -172,16 +176,18 @@ def __init__(self):
172176 mock_monte_carlo = MockMonteCarlo ()
173177 plots = _MonteCarloPlots (mock_monte_carlo )
174178
175- with pytest .raises (
176- ValueError , match = "MonteCarlo object must have an 'environment' attribute"
177- ):
179+ with pytest .raises (ValueError ) as exc_info :
178180 plots .ellipses (background = "satellite" )
181+ assert "environment" in str (exc_info .value ).lower ()
182+ assert "automatically fetching the background map" in str (exc_info .value )
179183
180184
181- def test_ellipses_background_no_latitude_longitude ():
185+ @patch ("matplotlib.pyplot.show" )
186+ def test_ellipses_background_no_latitude_longitude (mock_show ):
182187 """Test that ValueError is raised when environment has no latitude or longitude attributes.
183188
184189 This test creates a mock environment without latitude and longitude attributes.
190+ The function should raise ValueError when trying to fetch background map.
185191 """
186192 from rocketpy .plots .monte_carlo_plots import _MonteCarloPlots
187193
@@ -191,20 +197,28 @@ def test_ellipses_background_no_latitude_longitude():
191197
192198 mock_monte_carlo = MagicMock ()
193199 mock_monte_carlo .environment = mock_environment
200+ mock_monte_carlo .results = {
201+ "apogee_x" : [100 , 200 , 300 ],
202+ "apogee_y" : [100 , 200 , 300 ],
203+ "x_impact" : [1000 , 2000 , 3000 ],
204+ "y_impact" : [1000 , 2000 , 3000 ],
205+ }
206+ mock_monte_carlo .filename = "test"
194207
195208 plots = _MonteCarloPlots (mock_monte_carlo )
196209
197- with pytest .raises (
198- ValueError , match = "Environment must have 'latitude' and 'longitude' attributes"
199- ):
210+ with pytest .raises (ValueError ) as exc_info :
200211 plots .ellipses (background = "satellite" )
212+ assert "latitude" in str (exc_info .value ).lower ()
213+ assert "longitude" in str (exc_info .value ).lower ()
214+ assert "automatically fetching the background map" in str (exc_info .value )
201215
202216
203217@patch ("matplotlib.pyplot.show" )
204218def test_ellipses_background_contextily_not_installed (
205219 mock_show , monte_carlo_calisto_pre_loaded
206220):
207- """Test that a warning is issued when contextily is not installed.
221+ """Test that ImportError is raised when contextily is not installed.
208222
209223 Parameters
210224 ----------
@@ -226,16 +240,9 @@ def mock_import_optional_dependency(name):
226240 "rocketpy.plots.monte_carlo_plots.import_optional_dependency" ,
227241 side_effect = mock_import_optional_dependency ,
228242 ):
229- with warnings .catch_warnings (record = True ) as w :
230- warnings .simplefilter ("always" )
231- result = monte_carlo_calisto_pre_loaded .plots .ellipses (
232- background = "satellite"
233- )
234- assert result is None
235- assert len (w ) > 0
236- assert any (
237- "contextily" in str (warning .message ).lower () for warning in w
238- )
243+ with pytest .raises (ImportError ) as exc_info :
244+ monte_carlo_calisto_pre_loaded .plots .ellipses (background = "satellite" )
245+ assert "contextily" in str (exc_info .value ).lower ()
239246 finally :
240247 _post_test_file_cleanup ()
241248
@@ -286,3 +293,78 @@ def test_ellipses_background_save(mock_show, monte_carlo_calisto_pre_loaded):
286293 assert os .path .exists ("monte_carlo_test.png" )
287294 finally :
288295 _post_test_file_cleanup ()
296+
297+
298+ @patch ("matplotlib.pyplot.show" )
299+ def test_ellipses_background_invalid_provider (
300+ mock_show , monte_carlo_calisto_pre_loaded
301+ ):
302+ """Test that ValueError is raised when an invalid map provider is specified.
303+
304+ Parameters
305+ ----------
306+ mock_show :
307+ Mocks the matplotlib.pyplot.show() function to avoid showing the plots.
308+ monte_carlo_calisto_pre_loaded : MonteCarlo
309+ The MonteCarlo object, this is a pytest fixture.
310+ """
311+ try :
312+ with pytest .raises (ValueError ) as exc_info :
313+ monte_carlo_calisto_pre_loaded .plots .ellipses (
314+ background = "Invalid.Provider.Name"
315+ )
316+ assert "Invalid map provider" in str (exc_info .value )
317+ assert "Invalid.Provider.Name" in str (exc_info .value )
318+ assert (
319+ "satellite" in str (exc_info .value )
320+ or "street" in str (exc_info .value )
321+ or "terrain" in str (exc_info .value )
322+ )
323+ finally :
324+ _post_test_file_cleanup ()
325+
326+
327+ @patch ("matplotlib.pyplot.show" )
328+ def test_ellipses_background_bounds2img_failure (
329+ mock_show , monte_carlo_calisto_pre_loaded
330+ ):
331+ """Test that RuntimeError is raised when bounds2img fails to fetch map tiles.
332+
333+ Parameters
334+ ----------
335+ mock_show :
336+ Mocks the matplotlib.pyplot.show() function to avoid showing the plots.
337+ monte_carlo_calisto_pre_loaded : MonteCarlo
338+ The MonteCarlo object, this is a pytest fixture.
339+ """
340+ try :
341+ from rocketpy .tools import import_optional_dependency as original_import
342+ import contextily
343+
344+ # Create a mock contextily module with a failing bounds2img
345+ mock_contextily = MagicMock ()
346+ mock_contextily .providers = contextily .providers
347+
348+ def mock_bounds2img (* args , ** kwargs ):
349+ raise ConnectionError ("Network error: Unable to fetch tiles" )
350+
351+ mock_contextily .bounds2img = mock_bounds2img
352+
353+ def mock_import_optional_dependency (name ):
354+ if name == "contextily" :
355+ return mock_contextily
356+ return original_import (name )
357+
358+ with patch (
359+ "rocketpy.plots.monte_carlo_plots.import_optional_dependency" ,
360+ side_effect = mock_import_optional_dependency ,
361+ ):
362+ with pytest .raises (RuntimeError ) as exc_info :
363+ monte_carlo_calisto_pre_loaded .plots .ellipses (background = "satellite" )
364+ assert "Failed to fetch background map tiles" in str (exc_info .value )
365+ assert "satellite" in str (exc_info .value )
366+ assert "Network connectivity" in str (
367+ exc_info .value
368+ ) or "Service unavailability" in str (exc_info .value )
369+ finally :
370+ _post_test_file_cleanup ()
0 commit comments