import datetime import unittest from freezegun import freeze_time from unittest.mock import patch, MagicMock from urllib.error import HTTPError from doors import ZohoToken, authenticate class TestZohoToken(unittest.TestCase): """Test the ZohoToken class""" @patch('zoho_auth.request') def test_fetches_token(self, mock_request): """Test that the ZohoAuth class fetches a token from the web service""" mock_response = MagicMock() mock_response.read.return_value.decode.return_value = '{"access_token": "mock_access_token", "expires_in": 3600}' mock_request.urlopen.return_value.__enter__.return_value = mock_response token = ZohoToken('mock_client_id', 'mock_client_secret', 'mock_refresh_token') token.update_token() # Assert that the token was fetched self.assertEqual(token.get_token(), 'mock_access_token') mock_request.Request.assert_called_with('https://accounts.zoho.com/oauth/v2/token?refresh_token=mock_refresh_token&client_id=mock_client_id&client_secret=mock_client_secret&grant_type=refresh_token', method='POST') @patch('zoho_auth.request') @freeze_time('2009-06-15 09:00:00', as_kwarg='frozen_time') def test_updates_token_after_expiration(self, mock_request, frozen_time): """Test that ZohoAuth fetches a new token after the previous one expires""" mock_response = MagicMock() mock_response.read.return_value.decode.return_value = '{"access_token": "mock_access_token", "expires_in": 3600}' mock_request.urlopen.return_value.__enter__.return_value = mock_response token = ZohoToken('mock_client_id', 'mock_client_secret', 'mock_refresh_token') token.update_token() self.assertEqual(token.expires_at, datetime.datetime(2009, 6, 15, 10, 0, 0)) mock_response.read.return_value.decode.return_value = '{"access_token": "updated_mock_access_token", "expires_in": 3600}' frozen_time.tick(datetime.timedelta(seconds=3599)) self.assertEqual(token.get_token(), 'mock_access_token') frozen_time.tick(datetime.timedelta(seconds=1)) self.assertEqual(token.get_token(), 'updated_mock_access_token') @patch('zoho_auth.request') def test_authenticate_calls_service(self, mock_request): """Test that the authenticate function works""" token = MagicMock() token.get_token.return_value = 'mock_access_token' mock_response = MagicMock() mock_response.status = 200 mock_request.urlopen.return_value.__enter__.return_value = mock_response ret_val = authenticate(token, 'ABCDEF1234567890') mock_request.Request.assert_called_with('https://www.zohoapis.com/crm/v2/Contacts/search?criteria=%28Key_ID%3Aequals%3AABCDEF1234567890%29', method='GET', headers={ 'Authorization': 'Zoho-oauthtoken mock_access_token', }) self.assertTrue(ret_val) @patch('zoho_auth.request') def test_authenticate_fails_bad_key(self, mock_request): """Test that the authenticate function works""" token = MagicMock() token.get_token.return_value = 'mock_access_token' mock_response = MagicMock() mock_response.status = 204 mock_request.urlopen.return_value.__enter__.return_value = mock_response ret_val = authenticate(token, 'ABCDEF1234567890') self.assertFalse(ret_val) @patch('zoho_auth.request') def test_authenticate_fails_when_server_is_down(self, mock_request): """Test that the authenticate function works""" token = MagicMock() token.get_token.return_value = 'mock_access_token' error = HTTPError('https://www.youtube.com/watch?v=dQw4w9WgXcQ', 403, 'Forbidden', {}, None) mock_request.urlopen.return_value.__enter__.side_effect = error ret_val = authenticate(token, 'ABCDEF1234567890') self.assertFalse(ret_val) if __name__ == '__main__': unittest.main()