1+
12from datetime import datetime as dt
3+ from unittest .mock import patch , MagicMock
24from django .conf import settings
35from django .test import TestCase
46from django .utils .module_loading import import_string
5-
7+ import requests
8+ from requests .exceptions import JSONDecodeError , HTTPError , RequestException
69
710# manage.py test tests.crm.backends.test_currency_rate_backend
811MARKETING_CURRENCY = 'USD'
@@ -12,23 +15,91 @@ class TestCurrencyRateBackend(TestCase):
1215
1316 def setUp (self ):
1417 print (" Run Test Method:" , self ._testMethodName )
18+ if not settings .LOAD_RATE_BACKEND :
19+ self .skipTest ("LOAD_RATE_BACKEND is not set in settings." )
20+ try :
21+ self .be = import_string (settings .LOAD_RATE_BACKEND )
22+ except ImportError :
23+ self .fail (f"Failed to import backend: { settings .LOAD_RATE_BACKEND } " )
24+
1525
1626 def test_currency_rate_backend (self ):
17- if not any ((settings .LOAD_EXCHANGE_RATE , settings .LOAD_RATE_BACKEND )):
18- print ("Test `CurrencyRateBackend` skipped due to settings." )
19- return
20- be = import_string (settings .LOAD_RATE_BACKEND )
27+ # NOTE: This test depends on settings.LOAD_EXCHANGE_RATE = True and a valid LOAD_RATE_BACKEND.
28+ # It might perform a live API call if not mocked.
29+ # Consider mocking if live calls are undesirable.
30+ if not settings .LOAD_EXCHANGE_RATE :
31+ self .skipTest ("LOAD_EXCHANGE_RATE is False in settings. Skipping live test." )
32+
2133 today = dt .now ().date ()
22- state_currency = be .get_state_currency ()
23- if state_currency != MARKETING_CURRENCY :
24- backend = be (state_currency , MARKETING_CURRENCY , today )
25- rate_to_state_currency , rate_to_marketing_currency , error = backend .get_rates ()
26- self .assertEqual ('' , error )
34+ state_currency = self .be .get_state_currency ()
35+
36+ backend_state = self .be (state_currency , MARKETING_CURRENCY , today )
37+ rate_to_state_currency , rate_to_marketing_currency , error_state = backend_state .get_rates ()
38+
39+ if error_state :
40+ print (f"Warning: Live API call in test_currency_rate_backend (state) failed: { error_state } " )
41+ self .assertNotEqual ('' , error_state )
42+ else :
2743 self .assertEqual (rate_to_state_currency , 1 )
28- self .assertEqual (type (rate_to_marketing_currency ), float )
44+ self .assertIsInstance (rate_to_marketing_currency , (float , int ))
45+ if state_currency == MARKETING_CURRENCY :
46+ self .assertEqual (rate_to_marketing_currency , 1 )
47+
48+ backend_marketing = self .be (MARKETING_CURRENCY , MARKETING_CURRENCY , today )
49+ rate_to_state_usd , rate_to_marketing_usd , error_marketing = backend_marketing .get_rates ()
50+
51+ if error_marketing :
52+ print (f"Warning: Live API call in test_currency_rate_backend (marketing) failed: { error_marketing } " )
53+ self .assertNotEqual ('' , error_marketing )
54+ else :
55+ self .assertEqual (rate_to_marketing_usd , 1 )
56+ self .assertIsInstance (rate_to_state_usd , (float , int ))
57+ if state_currency == MARKETING_CURRENCY :
58+ self .assertEqual (rate_to_state_usd , 1 )
59+
60+ @patch ('crm.backends.bank_gov_ua_backend.requests.get' )
61+ def test_currency_rate_backend_json_error (self , mock_get ):
62+ mock_response = MagicMock (spec = requests .Response )
63+ mock_response .status_code = 200
64+ mock_response .text = 'invalid json'
65+ mock_response .json .side_effect = JSONDecodeError ("Expecting value" , mock_response .text , 0 )
66+ mock_response .raise_for_status = MagicMock ()
67+ mock_get .return_value = mock_response
68+
69+ backend = self .be ('EUR' , MARKETING_CURRENCY , dt .now ().date ())
70+ rate_to_state_currency , rate_to_marketing_currency , error = backend .get_rates ()
71+
72+ self .assertIn ("Failed to decode JSON response from API" , error )
73+ self .assertIn ("Status: 200" , error )
74+ self .assertIn ("Response text: invalid json" , error )
75+ self .assertEqual (rate_to_state_currency , 1 )
76+ self .assertEqual (rate_to_marketing_currency , 1 )
77+
78+ @patch ('crm.backends.bank_gov_ua_backend.requests.get' )
79+ def test_currency_rate_backend_http_error (self , mock_get ):
80+ mock_response = MagicMock (spec = requests .Response )
81+ mock_response .status_code = 500
82+ mock_response .text = 'Internal Server Error'
83+ http_error = HTTPError ("500 Server Error" , response = mock_response )
84+ mock_response .raise_for_status .side_effect = http_error
85+ mock_get .return_value = mock_response
86+
87+ backend = self .be ('EUR' , MARKETING_CURRENCY , dt .now ().date ())
88+ rate_to_state_currency , rate_to_marketing_currency , error = backend .get_rates ()
89+
90+ self .assertIn ("API request failed" , error )
91+ self .assertIn ("500 Server Error" , error )
92+ self .assertEqual (rate_to_state_currency , 1 )
93+ self .assertEqual (rate_to_marketing_currency , 1 )
94+
95+ @patch ('crm.backends.bank_gov_ua_backend.requests.get' )
96+ def test_currency_rate_backend_request_exception (self , mock_get ):
97+ mock_get .side_effect = RequestException ("Connection timed out" )
98+
99+ backend = self .be ('EUR' , MARKETING_CURRENCY , dt .now ().date ())
100+ rate_to_state_currency , rate_to_marketing_currency , error = backend .get_rates ()
29101
30- backend = be (MARKETING_CURRENCY , MARKETING_CURRENCY , today )
31- rate_to_state_currency , rate_to_marketing_currency , error = backend .get_rates ()
32- self .assertEqual ('' , error )
33- self .assertEqual (rate_to_marketing_currency , 1 )
34- self .assertEqual (type (rate_to_state_currency ), float )
102+ self .assertIn ("API request failed" , error )
103+ self .assertIn ("Connection timed out" , error )
104+ self .assertEqual (rate_to_state_currency , 1 )
105+ self .assertEqual (rate_to_marketing_currency , 1 )
0 commit comments